# sync.Cond

# 介绍

sync.Cond 是 Go 语言标准库中的一个条件变量,用于在多个 goroutine 之间进行同步和通信。它允许一个或多个 goroutine 等待某个条件变为真,然后通知其他等待的 goroutine 继续执行。

type Cond struct {
	noCopy noCopy 
	// L is held while observing or changing the condition
	L Locker // 每个 Cond 都有一个关联的 Locker L,在改变条件和调用 Wait 方法时,需要先获取 L 的锁
	notify  notifyList // 通知列表
	checker copyChecker // 复制检查器
}

# 方法

# NewCond 构造函数

func NewCond(l Locker) *Cond {
	return &Cond{L: l}
}

# Wait 等待

Wait 方法会使当前 goroutine 进入等待状态,直到收到通知或被广播。调用 Wait 方法前,需要先获取 c.L 的锁,并在调用 Wait 方法后释放 c.L 的锁。Wait 方法会自动释放 c.L 的锁,并在收到通知或被广播后重新获取 c.L 的锁。

func (c *Cond) Wait() {
	c.checker.check()
	t := runtime_notifyListAdd(&c.notify)
	c.L.Unlock()
	runtime_notifyListWait(&c.notify, t)
	c.L.Lock()
}

# Signal 通知一个等待的 goroutine

Signal 方法会通知一个等待的 goroutine 继续执行。
允许但不要求调用者在调用过程中持有 c.L 的锁。

func (c *Cond) Signal() {
	c.checker.check()
	runtime_notifyListNotifyOne(&c.notify)
}

# Broadcast 通知所有等待的 goroutine

Broadcast 方法会通知所有等待的 goroutine 继续执行。
允许但不要求调用者在调用过程中持有 c.L 的锁。

func (c *Cond) Broadcast() {
	c.checker.check()
	runtime_notifyListNotifyAll(&c.notify)
}

# 使用场景

sync.Cond 通常用于以下场景:

  1. 生产者 - 消费者模型:当生产者生产出产品后,通知消费者进行消费;当消费者消费完产品后,通知生产者继续生产。在这种情况下,可以使用 sync.Cond 来实现生产者和消费者之间的同步。
var (
	mux   = sync.Mutex{}
	cond  = sync.NewCond(&mux)
	queue []int
)
func producer(count int) {
	for i := 0; i < count; i++ {
		mux.Lock()
		queue = append(queue, i+1)
		fmt.Println("produced:", i+1)
		cond.Signal()
		mux.Unlock()
	}
}
func comsumer() {
	for {
		mux.Lock()
		for len(queue) == 0 {
			cond.Wait()
		}
		fmt.Println("consumed:", queue[0])
		queue = queue[1:]
		mux.Unlock()
	}
}
func main() {
	go comsumer()
	go producer(100)
	time.Sleep(time.Second)
}
  1. 多协程同步:当多个 goroutine 需要等待某个条件变为真时,可以使用 sync.Cond 来实现同步。

# 使用方法

sync.Cond 的使用方法如下:

  1. 创建一个 sync.Cond 对象:可以使用 sync.NewCond(&sync.Mutex{}) 来创建一个 sync.Cond 对象,其中 sync.Mutex 是用于保护条件的互斥锁。
  2. 调用 Wait 方法:在需要等待某个条件变为真的地方,调用 sync.Cond 对象的 Wait 方法,该方法会使当前 goroutine 进入等待状态,直到收到通知或被广播。
  3. 调用 SignalBroadcast 方法:在条件变为真的地方,调用 sync.Cond 对象的 SignalBroadcast 方法,该方法会通知一个或所有等待的 goroutine 继续执行。

# 注意事项

  1. 在调用 Wait 方法前,需要先获取 sync.Cond 对象的互斥锁。
  2. 在调用 SignalBroadcast 方法前,需要先获取 sync.Cond 对象的互斥锁。
  3. sync.Cond 对象的互斥锁需要在调用 Wait 方法前获取,并在调用 Wait 方法后释放,以确保在等待期间不会发生竞争条件。
  4. sync.Cond 对象的互斥锁需要在调用 SignalBroadcast 方法前获取,并在调用 SignalBroadcast 方法后释放,以确保在通知期间不会发生竞争条件。

# 总结

sync.Cond 是 Go 语言标准库中的一个条件变量,用于在多个 goroutine 之间进行同步和通信。它允许一个或多个 goroutine 等待某个条件变为真,然后通知其他等待的 goroutine 继续执行。 sync.Cond 的使用方法简单,但在使用时需要注意互斥锁的获取和释放,以避免竞争条件。

更新于 阅读次数

请我喝[茶]~( ̄▽ ̄)~*

ZJM 微信支付

微信支付

ZJM 支付宝

支付宝