golang 系列(sync.Cond 机制)
前言
在 Go 里有专门为同步通信而生的 channel,所以较少看到 sync.Cond 的使用。不过它也是并发控制手段里的一种,今天我们就来认识下它的相关实现,加深对同步机制的运用。
sync.Cond
【golang 系列(sync.Cond 机制)】sync.Cond 提供了三个方法:Wait()、Signal()、Broadcast(),它们的用法如下:
- Wait():阻塞当前的 goroutine,等待唤起。
- Signal():唤起一个阻塞的 goroutine。
- Broadcast():唤起所有阻塞的 goroutine。
当有一个任务到来时,则通过 Signal() 唤起刚刚在阻塞的某一个 goroutine,去执行任务。
通过任务池功能,我们发现 sync.Cond 的运用很简单,但 Go 官方并不推荐我们使用 sync.Cond 来实现协程间的同步通信。
因为它并不符合 Go 官方 “通过通信来共享内存” 的设计思想,当场景复杂时,则会耦合各个业务功能。
sync.Cond 源码分析
我们来看下 sync.Cond 的结构体,代码在 /sr/sync/cond.go 下:
type Cond struct {
noCopy noCopy// 不可复制
L Locker// 锁
notifynotifyList// 通知唤起列表
checker copyChecker // 复制检测
}
可以看到 Cond 上有 notify 列表,而这正是维护了需要唤起的 goroutine 列表。
当我们调用 Wait() 方法的时候就会维护当前 goroutine 到对应的 notifyList 里:
func (c *Cond) Wait() {
c.checker.check()
t := runtime_notifyListAdd(&c.notify) // 将当前 goroutine 添加到 notifyList 里
c.L.Unlock()
runtime_notifyListWait(&c.notify, t) // 阻塞等待
c.L.Lock()
}
当有其他协程调用了 Signal 或 Broadcast 方法时,则会通过
runtime_notifyListNotifyOne
或runtime_notifyListNotifyAll
方法来唤起一个或多个 goroutine。其他同步方式的实现
前面提到到 sync.Cond 并不被推荐作为协同通信手段,那如果要实现它的单播、广播效果,该怎么弄呢?
其实也很简单,如果我们要实现单播效果,那么只需要通过阻塞的监听 channel 信号即可。
如果要实现广播唤起效果,只需要利用 context 的链式取消特性,也能达到该效果。
感兴趣的朋友可以搜一搜公众号「 阅新技术 」,关注更多的推送文章。
可以的话,就顺便点个赞、留个言、分享下,感谢各位支持!
阅新技术,阅读更多的新知识。
文章图片
推荐阅读
- 【欢喜是你·三宅系列①】⑶
- 你不可不知的真相系列之科学
- 人脸识别|【人脸识别系列】| 实现自动化妆
- 2018-06-13金句系列7(金句结构-改编古现代诗词)
- Unity和Android通信系列文章2——扩展UnityPlayerActivity
- 乡野村趣系列之烧仙草
- Java内存泄漏分析系列之二(jstack生成的Thread|Java内存泄漏分析系列之二:jstack生成的Thread Dump日志结构解析)
- 15、IDEA学习系列之其他设置(生成javadoc、缓存和索引的清理等)
- 【年终激励系列】之五(年终奖如何与考核紧密相连)
- 剥削劳动力系列(企业家剥削你时,他要付出巨大的代价)