golang中的Cond条件变量讲解

cond是什么

  1. Cond实现了一种条件变量,可以使用在多个reader等待共享资源ready的场景,(如果只有一读一写,一个锁或者channel就搞定了)
  2. 每个Cond都会关联一个Lock(*sync.Mutex or *sync.RWMutex), 当修改条件或者调用Wait方法时,必须加锁以保护condition
  3. 案例:
var (
	c = sync.Cond{L: &sync.Mutex{}}  // 条件变量,多个reader等待共享资源ready的场景
	maxNum = 15
)
func main(){
	for i := 0; i < maxNum; i++{
		go func(i int) {
			c.L.Lock()
			defer c.L.Unlock()
			// Wait会释放c.L锁,并挂起调用者的goroutine,之后恢复执行
			c.Wait()  // Wait会在返回时对c.L加锁
			// 除非被Broadcast或Signal唤醒,否则Wait不会返回
			fmt.Println("goroutine:", i)
			time.Sleep(time.Millisecond * 100)
		}(i)
	}
	c.L.Lock()
	maxNum = 16
	c.L.Unlock()
	c.Broadcast()  // 广播,所有等待的goroutine都会执行
	//c.Signal()  // 单播,从所有等待的goroutine中随机找一个去执行
	time.Sleep(time.Second * 2)
}

Broadcast和Signal的区别

  • Broadcast会唤醒所有等待c的goroutine,调用Broadcast的时候,可以加锁也可以不加锁
  • Signal只唤醒一个等待c的goroutine,调用Signal的时候,可以加锁也可以不加锁

Cond中Wait使用

  1. Wait会自动释放c.L锁,并挂起调用者的goroutine,之后恢复执行
  2. Wait会在返回时对c.L加锁
  3. 除非被Broadcast或Signal唤醒,否则Wait不会返回
  4. 由于Wait第一次恢复是,c.L并没有加锁,所以当Wait返回时,调用者通常不能假设条件为真
  5. 简单来说,只要想使用condition就必须加锁
posted @ 2022-01-25 10:52  专职  阅读(597)  评论(0编辑  收藏  举报