大家好我是小西,从今天开始,我将开始更新Go基础篇的笔记
预计有n篇,哈哈其实我也不知道有几篇,基础篇写完了,再写应用篇,大致是这个计划
老手可以回顾回顾 ,温故知新~ 新手可以收藏一下 做个参考
今天更新第六篇,内容是 Go 并发 RWMutex 和 WaitGroup 先来回顾一下上期的内容for+select 可以同时处理多个 channel , default 分支可以放在select 内部,处理全部阻塞的逻辑。
因为在多核CPU 上 go routine 是同时执行的代码片段,为了让 go routine 操作同一个变量所以我们必需引入 Mutex 锁, (这时变量是一种资源,因在程序中他只有一份 ,大家必须排队,受限制地来访问和修改它 )。上锁后只有当前的 go routine 能访问函数中的变量,其它go rountie 会阻塞直到解锁。
其实锁在Go中会点复杂,你需要上锁解锁,而代码虽然还是并发执行的,但执行性能会大幅下降,因为有很多的阻塞等待
RWMutex 解决了什么问题
Sync.Mutex 上锁后,只有一个go runtine 临界区代码可执行,其它的go routune 处于等待状态。
RWMutex 没有 Mutex 这么严格,他分为读锁和读写锁两把锁
Lock是读写锁,上锁后,全部的go routine 的读写操作都会阻塞
Rlock 是读锁,上锁后,全部的读 go routine 不受影响,但是不让写
因为会导致数据错乱
每个 go routine 在读取 data 时要先尝试拿到读锁,确保没有其它 go routine 在写
每个 go routine 在修改 data 时要先尝试拿到写锁,确认没有其它 go routine 在读或在写
WaitGroup 是怎么使用的
上面的代码中我看到有 sync.WaitGroup , 他就是一个指挥者,管理多个 go runtine
他有以几个特点
- 先定义再使用 var wg sync.WaitGroup
- 有 go 就 +1 wg.Add(1) 代表有一个 go routine 进组了
- Go routine 完成就 wg.Done() 通常在 go routine 内部第一行使用 defer 调用
- 使用 Wait() 等他们干完活,程序才会继续向下执行
最后
本期内容就到这里吧,内部不多两个知识点
希望通过本文,你对 Go 中的并发编程有深入的了解
关于并发目前有三篇文章了,看来Go中的并发编程还蛮重要的
感谢你看到这里,如果喜欢本教程,欢迎你分享给在学习编程的朋友~
我是小西,下周见~