Go语言并发编程中Cond 中 Wait 使用

发布于 1周前 作者 songsunli 最后一次编辑是 5天前 来自 问答

Go语言并发编程中Cond 中 Wait 使用

func (c *Cond) Wait()

Wait()会自动释放 c.L 锁,并挂起调用者的 goroutine。之后恢复执行, Wait()会在返回时对 c.L 加锁。 除非被 Signal 或者 Broadcast 唤醒,否则 Wait()不会返回。 由于 Wait()第一次恢复时,C.L 并没有加锁,所以当 Wait 返回时,调用者通常 并不能假设条件为真。如下代码:。 取而代之的是, 调用者应该在循环中调用 Wait。(简单来说,只要想使用 condition,就必须加锁。)

c.L.Lock()
for !condition() { c.Wait()
}
... make use of condition ...
c.L.Unlock()
1 回复

在Go语言的并发编程中,sync.Cond 是一个用于等待/通知(等待某个条件成立)的同步原语,它通常与互斥锁(如 sync.Mutex)一起使用,以确保条件检查和条件变量的等待/通知操作是原子的。sync.CondWait 方法用于阻塞调用它的goroutine,直到另一个goroutine调用 SignalBroadcast 方法。

使用 sync.CondWait 方法

在使用 sync.CondWait 方法时,你首先需要确保 sync.Cond 是与某个互斥锁(比如 sync.Mutex)关联的。在调用 Wait 方法之前,必须先加锁,并且在 Wait 方法内部,锁会被自动释放并在等待的goroutine被唤醒时重新获取。

下面是一个简单的示例,展示了如何在Go语言中使用 sync.CondWait 方法:

package main

import (
	"fmt"
	"sync"
	"time"
)

// 定义一个条件变量
var cond = sync.NewCond(&sync.Mutex{})

// 条件变量监控的变量
var ready = false

func main() {
	// 等待者goroutine
	go waiter()

	// 时间后设置ready为true并通知
	time.Sleep(1 * time.Second)
	cond.L.Lock() // 加锁
	ready = true  // 设置条件变量
	cond.Signal() // 发送信号
	cond.L.Unlock() // 解锁

	// 防止main函数立即退出
	time.Sleep(2 * time.Second)
}

func waiter() {
	cond.L.Lock() // 加锁
	defer cond.L.Unlock() // 解锁,但注意Wait内部也会解锁并重新加锁

	// 等待条件变量ready变为true
	for !ready {
		cond.Wait() // 等待,直到收到Signal或Broadcast
	}

	fmt.Println("Condition met!")
}

在这个例子中,waiter 函数中的goroutine将一直等待,直到主函数中的 cond.Signal() 被调用并且 ready 变量被设置为 true。注意,在调用 cond.Wait() 之前和之后都需要加锁和解锁,但 cond.Wait() 内部会自动处理锁的释放和重新获取,以避免死锁。

使用 sync.Cond 时需要特别注意锁的管理,确保在正确的时机加锁和解锁,以避免竞态条件和其他并发问题。

回到顶部