知识卡片
互斥锁保护不变量
内容
锁保护的不是代码块本身,而是一组共享状态的不变量。临界区越小越好,但必须覆盖状态从读取、判断到写回的完整过程,否则仍会出现竞态。
参考来源
- 位置:《Go语言底层原理剖析》第17章《并发控制》17.3.3节《race工具原理》与17.4.2节《互斥锁》
- 结论依据:原文用锁保护 count 变量的例子说明"对count的访问用锁进行保护,就不会触发数据争用,因为一个协程对count的访问必须等待另一个协程的锁释放后才能开始",并在互斥锁一节指出"sync.Mutex构建起了互斥锁,在同一时刻,只会有一个获取锁的协程继续执行",说明锁保护的是被并发访问的共享状态整体而不仅是某一行代码,因此可以推出"锁保护的是共享状态的不变量、覆盖读-判断-写回的完整过程"的结论。
- 原始内容:下例如果对count的访问用锁进行保护,就不会触发数据争用,因为一个协程对count的访问必须等待另一个协程的锁释放后才能开始……通过原子操作构建起的互斥锁,虽然高效而且简单,但是其并不是万能的……Go语言拥有比线程更加轻量级的协程,在协程的基础上实现了一种比传统操作系统级别的锁更加轻量级的互斥锁……sync.Mutex构建起了互斥锁,在同一时刻,只会有一个获取锁的协程继续执行,而其他的协程将陷入等待状态。