Cond 实现了一个条件变量,在 Locker 的基础上增加的一个消息通知的功能,保存了一个通知列表,用来唤醒一个或所有因等待条件变量而阻塞的 Go 程,以此来实现多个 Go 程间的同步。
type Cond struct {
// L is held while observing or changing the condition
L Locker
// contains filtered or unexported fields
}
// 创建一个带锁的条件变量,Locker 通常是一个 *Mutex 或 *RWMutex
func NewCond(l Locker) *Cond
// 唤醒所有因等待条件变量 c 阻塞的 goroutine
func (c *Cond) Broadcast()
// 唤醒一个因等待条件变量 c 阻塞的 goroutine
func (c *Cond) Signal()
// 等待 c.L 解锁并挂起 goroutine,在稍后恢复执行后,Wait 返回前锁定 c.L,只有当被 Broadcast 和 Signal 唤醒,Wait 才能返回
func (c *Cond) Wait()
注意:在调用 Signal,Broadcast 之前,应确保目标 Go 程进入 Wait 阻塞状态。
Cond代码示例:
package main
import (
"fmt"
"sync"
"time"
)
var locker = new(sync.Mutex)
var cond = sync.NewCond(locker)
func main() {
for i := 0; i < 10; i++ {
go func(x int) {
cond.L.Lock() //获取锁
defer cond.L.Unlock() //释放锁
cond.Wait() //等待通知,阻塞当前goroutine
fmt.Println(x)
}(i)
}
time.Sleep(time.Second * 1) // 睡眠1秒,使所有goroutine进入 Wait 阻塞状态
fmt.Println("Signal...")
cond.Signal() // 1秒后下发一个通知给已经获取锁的goroutine
time.Sleep(time.Second * 1)
fmt.Println("Signal...")
cond.Signal() // 1秒后下发下一个通知给已经获取锁的goroutine
time.Sleep(time.Second * 1)
cond.Broadcast() // 1秒后下发广播给所有等待的goroutine
fmt.Println("Broadcast...")
time.Sleep(time.Second * 1) // 睡眠1秒,等待所有goroutine执行完毕
}
多次运行结果不一致,示例输出:
Signal...
4
Signal...
0
Broadcast...
7
1
2
3
5
9
6
8
注意:条件变量和锁结合使用,在并发时如果逻辑不严谨容易发生死锁,所以尽量不要使用条件变量,推荐用 sync.WaitGroup 来实现并发时 Go 程间的同步。
[1] Package sync.Cond [2] Golang Cond源码分析
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有