Go语言进阶overview | 青训营

105 阅读2分钟

Go语言进阶overview

内容:Go的并发简介,依赖管理演进与比较,版本与module路径。

并发与并行

并发是指多个线程在同一cpu上进行处理;

并行是指多个线程在多个cpu上处理;

Go与高并发

Go语言拥有goroutine,天然高并发;

goroutine是比线程更小的单位,你可以理解为用户态的协程,而线程为内存态;

具体大小方面,协程为栈KB级别,线程为栈MB级别;

CSP

通过通讯共享内存

前面说过,goroutine是Go语言天然高并发的优势所在,而不同的goroutine之间必然要有数据的交流,这种数据交流在Go中需要用csp的思想来实现,落实到具体,用了channel这一数据类型,它就像一个管道,在不同的goroutine之间起到了通讯的作用。

之所以采取CSP,是因为其能达到以下几个效果:

1.避免多个goroutine同时修改某一变量导致的竞态条件;

2.易于理解,维护代码;

3.提高了并发性能;

原先,需要加锁,解锁以保障安全,现在省去了这些步骤,性能得到提高;

前面讲CSP时讲到一种情况,多个goroutine同时修改某一个变量,会引起竞态条件,导致结果不可预料,我们可以采取锁的方式来解决;

var (
	x int64
	lock sync.Mutex
)
func addFunc()  {
	lock.Lock()
	defer lock.Unlock()
	x++
}

依赖管理

  • Go依赖版本的演进之路:

    GOPATH—VENDER—GOMODULE

    值得注意的是,module推出后,在可访问公网环境下,已经不需要vender这个文件夹了,但是GOPATH依旧保存下来,module只是替代了它的包管理功能,GOPATH依旧持有存放包,存放可执行文件等功能。

  • GOPATH三大文件夹: bin : 存放二进制文件

    pkg: 存放项目编译的中间产物,便于加速

    src: 存放包的源码

三大时代的比较:

GOPATH时代,由于所有依赖的包均放在同一文件夹下,我们无法处理多版本包的问题;

Vender时代,为每一个项目引入依赖的副本,当需要新版本时,无法方便的更新,同时容易引起依赖冲突问题;

Module时代,通过go.mod文件,go get,GOPROXY这三个核心,我们可以解决依赖问题,

我们可以使用go mod init来初始化项目,当我们需要添加依赖包时,只需使用go get modulepath,就可以快速获得依赖包;

注意:在项目严格遵循语义化版本的前提下,假设当前版本为v2.13.2,那么同一主版本下的不同次版本还有补包都是共享同一个module引入路径,不同主版本号(如 v1.13.2, v3.4.0)有不同的引入路径。