这是我参与「第五届青训营 」伴学笔记创作活动的第 2 天
Go语言进阶与依赖管理 | 青训营笔记
Go与并发
基本概念
Go实现了并发性能高的调度模型,充分发挥多核计算机的优势
协程:用户态,轻量级线程,栈KB级别,比线程轻量
线程:内核态,线程跑多个协程,栈MB级别,可跑多个协程
协程的使用
案例:快速打印hello
- 在函数前加一个go关键字,即可为函数创建一个协程
- 加sleep堵塞是为了保证在子协程完成前主协程不退出
- 从输出来看,是乱序输出的,所以打印是并行打印的
协程间通信
Go提倡通过通信共享内存
- goroutine是程序执行的主体,channal对goroutine做了连接
- 保留了通过共享内存通信的方式,通过互斥量加锁
提倡第一种:通过通信共享内存。第二种有性能问题。
Channal
make(chan 元素类型,[缓冲大小(不写即无缓冲通道)])
区别
无缓冲通道:发送和接受goroutine同步化,也称同步通道
有缓冲通道:会有阻塞问题。典型生产消费模型,可以解决生产消费速度差异问题(生产速度可能比消费速度快)
共享内存案例
addWithLock:加锁保护临界区,输出正确
addWithoutLock:并发安全问题,有一定概率引起错误出现,比较难定位,此类问题应尽量避免
WaitGroup
可实现并发任务的同步,内部维护了一个计数器。 案例:对快速打印hello优化
Add:计数器+5,有5个子协程
Done:完成一个协程
Wait:阻塞主协程知道所有子协程完成
补: Lock和WaitGroup都在sync包下
Go的依赖管理
演进
GOPATH -> GO Vender -> Go Module
目标:
- 不同环境(项目)依赖版本不同
- 控制依赖库的版本
GOPATH
- 项目代码直接依赖src下代码
- go get下载最新版本包到src目录下
问题:无法实现package的多版本控制
Go Vender
项目文件夹下建一个vender文件夹,优先在vender下寻找依赖,没有则回源到GOPATH下
问题: 可能出现依赖冲突
Go Module
- 通过go.mod文件管理依赖包版本
- 通过go get/go mod指令工具管理依赖包
依赖管理三要素
- 配置文件,描述依赖:go.mod
- 中心仓库管理依赖库:proxy
- 本地工具: go get/mod
MAJOR:大版本,可以理解为大版本间代码隔离
MINOR:新增函数
PATCH:代码bug修复