go语言进阶与依赖管理
这是我参与「第五届青训营 」伴学笔记创作活动的第 2 天
go语言进阶
并发和并行
协程 Goroutine
- 协程:用户态,轻量级的线程,在切换的时候不需要切换到内核态,减少了变态的开销,栈空间在KB级别。
- 线程:内核态,一个线程可以具有多个协程,栈空间在MB级别
上面的图片有一点问题,协程和线程的栈空间的大小写反了
实例:Goroutine 快速打印hello
利用go关键字即可创建协程,这里有内联的函数定义,同时在定义之后里面通过括号进行调用
CSP
go语言提倡通过通信共享内存,而不是通过共享内存而实现通信,go语言具有两种协程通信机制,下面有一篇参考文章:
在GO中 通过 通信共享内存 | Go主题月 - 掘金 (juejin.cn)
通过对上面内容的阅读,我们知道,传统的C++、Java语言当中鼓励使用共享内存实现线程之间的通信,而变量使用锁机制来保证互斥访问变量,而在go语言当中,鼓励使用通过机制,通道机制更加类似于一种信号的传递,一个进程操作完变量之后再通过通道传输告诉另外的goroutine,这样也可以保证对变量的互斥访问。
Channel
make(chan 元素类型, [缓冲大小])
- 无缓冲通道
- 有缓冲通道
简单的使用
并发安全问题
预期结果是10000,而不使用锁的机制的话,就会出现变量错误访问问题。
WaitGroup
这个位置的操作就类似于利用join的操作,让主线程等待子进程结束之后再结束
依赖管理
GOPATH
- go语言支持的环境变量
- cd $GOPATH; tree -L 1
- bin 项目编译的二进制文件
- pkg 项目编译的中间产物,加速编译
- src 项目源码
- 无法实现版本控制
Go Vendor
也就是对于不同的包的不同依赖存不同的版本
Go Module
- 通过 go.mod 文件管理依赖包版本
- 通过 go ger/go mod 指令工具管理依赖包
基本结构
依赖配置-version
标注
- indirect 不是直接的引用,而是间接的,例如A引用B包,B引用C包,那么A间接引用C包
- incompatible 可能存在不相互兼容的代码逻辑
依赖管理的依赖图
会选择最低的兼容版本,如果存在更高的版本也不会使用
依赖分发-回溯
依赖分发-Proxy
Proxy会缓存包的一些版本