一、什么是Cond?

Cond实现了一个条件变量,它是一个/多个goroutine等待或宣布事件发生的集合点。
每个Cond都有一个相关联的锁定器L(通常是*Mutex或*RWMutex),当改变条件和调用Wait方法时必须持有该锁。
Cond在第一次使用后不得复制。

二、Cond 结构体

type Cond struct {noCopy noCopy// L is held while observing or changing the conditionL Lockernotify  notifyListchecker copyChecker
}

noCopy:防止Cond复制

L Locker:锁接口,必须实现Lock、Unlock方法

notify:通告链表

checker:copyChecker保留指向自身的指针来检测对象复制。

三、方法

1. NewCond - 实例化Cond
func NewCond(l Locker) *Cond {return &Cond{L: l}
}

2. Wait - 阻塞当前gorotine,并等待Signal/Broadcast方法唤醒,前提是先获得锁(Lock()),然后执行Wait,再释放锁(Unlock)

func (c *Cond) Wait() {c.checker.check() //检测Cond是否被复制,如果被复制,则panic//将当前goroutine添加到等待队列(Cond.notify)t := runtime_notifyListAdd(&c.notify)c.L.Unlock()// 解锁;调用Wait前,需要加锁//进入睡眠,等待被唤醒runtime_notifyListWait(&c.notify, t)c.L.Lock() // 加锁,调用Wait之后,需要解锁
}

3. Signal - 唤醒一个goroutine(Cond.notify)

func (c *Cond) Signal() {c.checker.check() // 检测Cond是否被复制,如果被复制,则panic//唤醒一个notify链表里的goroutineruntime_notifyListNotifyOne(&c.notify)
}

4.Broadcast - 唤醒所有睡眠中的goroutine(Cond.notify)

func (c *Cond) Broadcast() {c.checker.check() //检测Cond是否被复制,如果被复制,则panic//唤醒所有goroutineruntime_notifyListNotifyAll(&c.notify)
}

四、noCopy

noCopy可以嵌入到第一次使用后不能复制的结构体中。

type noCopy struct{}// Lock is a no-op used by -copylocks checker from `go vet`.
func (*noCopy) Lock()   {}
func (*noCopy) Unlock() {}

五、copyChecker

copyChecker保留指向自身的指针来检测对象复制。

type copyChecker uintptrfunc (c *copyChecker) check() {if uintptr(*c) != uintptr(unsafe.Pointer(c)) &&!atomic.CompareAndSwapUintptr((*uintptr)(c), 0, uintptr(unsafe.Pointer(c))) &&uintptr(*c) != uintptr(unsafe.Pointer(c)) {panic("sync.Cond is copied")}
}

六、小结

Cond使用NewCond注入锁,获取Cond指针;

调用Lock加锁,调用Wait使当前goroutine进入睡眠,唤醒后,使用Unlock解锁。

唤醒方式:Signal,Broadcast

进一步阅读:

Cond中的notify,在runtime/sema.go,notifyList对应的方法也在其中,runtime_notifyListAdd、runtime_notifyListWait、runtime_notifyListNotifyOne、runtime_notifyListNotifyAll

sema.go中的代码都有相关注释,稍加思索,便可以明白其中的原理。

go sync.Cond 源码解析相关推荐

  1. go学习笔记 sync/Cond源码

    Cond需要指定一个Locker,通常是一个*Mutex或*RWMutex. func (c *Cond) Broadcast() 和 func (c *Cond) Signal() 唤醒因wait ...

  2. Colly源码解析——结合例子分析底层实现

    通过<Colly源码解析--框架>分析,我们可以知道Colly执行的主要流程.本文将结合http://go-colly.org上的例子分析一些高级设置的底层实现.(转载请指明出于break ...

  3. 死磕 java同步系列之ReentrantReadWriteLock源码解析

    问题 (1)读写锁是什么? (2)读写锁具有哪些特性? (3)ReentrantReadWriteLock是怎么实现读写锁的? (4)如何使用ReentrantReadWriteLock实现高效安全的 ...

  4. kube-proxy源码解析

    kube-proxy源码解析 ipvs相对于iptables模式具备较高的性能与稳定性, 本文讲以此模式的源 码解析为主,如果想去了解iptables模式的原理,可以去参考其实现,架构上无差别. ku ...

  5. Go http源码解析(一)

    Go web之旅 此篇开始将开启Go web之旅,我将这趟旅途分为三个子旅程: 源码解析 框架解读 中间件使用 所以在这趟旅途中我们将领略源码之雄伟,框架之奇艳,中间件之灵秀.在接下来的时间里我会按照 ...

  6. 多线程(三)之ReentrantLock源码解析

    2019独角兽企业重金招聘Python工程师标准>>> 今天分析ReentrantLock类的源码,在看源码之前,先学习AQS(AbstractQueuedSynchronizer) ...

  7. dubbo源码解析(九)远程通信——Transport层

    远程通讯--Transport层 目标:介绍Transport层的相关设计和逻辑.介绍dubbo-remoting-api中的transport包内的源码解析. 前言 先预警一下,该文篇幅会很长,做好 ...

  8. Android Lifecycle源码解析(一)

    Android Lifecycle源码解析(一) 首先我们看HomeActivity中我们添加到一行代码 public class HomeActivity extends AppCompatActi ...

  9. latch.await java有什么作用_java相关:CountDownLatch源码解析之await()

    java相关:CountDownLatch源码解析之await() 发布于 2020-6-18| 复制链接 摘记: CountDownLatch 源码解析-- await(),具体内容如下上一篇文章说 ...

最新文章

  1. android课程设计录音机,[转载]数字录音机(微机原理与接口技术-课程设计)
  2. 万维网发布服务 w3svc 已停止 除非万维_W3C万维网联盟宣布停止发布HTML 5.3版
  3. 处理xmpp 离线信息,
  4. C学习if条件判断和for循环
  5. Linux之ansible 自动化运维工具
  6. java微信h5支付_java 微信H5支付
  7. 【阅读推荐】改变你思维模式的书单
  8. Python一个命令开启http下载服务器
  9. 这条命令帮我在一分钟内修改了200台远程服务器密码!
  10. web前端学习第三周
  11. java listview用法_2.4.5 ListView简单实用
  12. 2007版本中国网络新秀之七剑下天山
  13. 常见的27个电源符号
  14. 视频摘要和视频浓缩的区别
  15. 短视频运营详解:抖音变现目前流行的是七种方式之一电商卖货
  16. 小x与三角形 c语言 1秒,[2019年第一水] 小x与神牛
  17. Python入门习题大全——猫和狗
  18. Axure RP 8.1 下载(附汉化+注册码)
  19. AcWing 1089 烽火传递 题解(动态规划—DP—单调队列优化DP)
  20. 合肥火车站为乌鲁木齐疼痛男孩开辟绿色通道

热门文章

  1. SAP License:SAP系统备料发货时的流程规范
  2. 20个基于DPDK开源项目,建议收藏
  3. 3.28leet28
  4. 【工欲善其事必先利其器】论文编辑及文献管理(Endnote,Latex,JabRef ,overleaf)资源下载及使用指南
  5. 我的世界服务器文件翻译,我的世界server.properties翻译 联机参数设置攻略
  6. fatal error C1001: INTERNAL COMPILER ERROR(compiler file 'msc1.cpp', line 1786)解决方法
  7. WinForm 窗体的边框
  8. 2021年的保研之旅总结
  9. Python股票数据爬虫解读
  10. 正片叠底(Multiply)和滤色(Screen)是两种基本的混合模式