这是我参与「第五届青训营 」伴学笔记创作活动的第 2 天
下面主要是我个人听课时的一些笔记
个人笔记
-
使用
WaitGroup优雅地实现协程同步主要是三个方法
-
Add(delta int)会使计数器加delta
-
Done()会使计数器减一
-
Wait()阻塞直到计数器为零
实际使用:在开启n个协程的时候
Add(n)在每个协程结束都
defer Done()在主协程使用
Wait()阻塞等待子协程结束 -
-
Golang中的互斥锁和原子操作
互斥锁的实现主要是基于
sync.Mutex和和sync.RWMutex原子操作的实现依赖于
sync/atomic这里补充一下原子操作和互斥锁的区别:
-
原子操作:
所谓原子操作是指不会被线程调度机制打断的操作;这种操作一旦开始,就一直运行到结束,中间不会有任何 context switch (线程切换)。
为了实现这样的严谨性,原子操作仅会由一个独立的CPU指令代表和完成。原子操作是无锁的,常常直接通过CPU指令直接实现。事实上,其它同步技术的实现常常依赖于原子操作。
-
互斥锁:
互斥锁用来保证临界区的安全性,确保在并发场景下,同一时刻,只会有一个线程持有锁,拥有访问临界区的权限。
-
-
Golang提倡通过通信来共享内存,而不是通过共享内存来通信
前者就是channel
尽管不提倡后者,但golang也支持后者,即通过
sync.Mutex来实现对临界区的并发安全保证 -
Golang中的依赖管理
GOPATH→Go Vendor→Go Module
-
GOPATH
GOPATH是Go语言支持的一个环境变量,其value是Go项目的工作区
弊端:无法实现package的多版本控制
-
Go Vendor
Vendor 是当前项目中的一个目录,其中存放了当前项目依赖的副本(等于是给每个项目添加了其依赖的副本)
弊端:
- 无法控制依赖的版本
- 更新项目可能又出现依赖冲突,导致编译出错
-
Go Module
最新的依赖管理方式
新建项目后
go mod init projectNamego mod tidy
在上述Golang的多种依赖管理方式的历史遗留背景下,体会到VSCode很难优雅地对Golang项目进行依赖管理,还得是Goland
-
参考
- 字节内部课—Go 语言进阶 - 工程进阶
- 原子操作和互斥锁的区别