Go语言并发编程中Cond 中 Wait 使用
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()
在Go语言的并发编程中,sync.Cond
是一个用于等待/通知(等待某个条件成立)的同步原语,它通常与互斥锁(如 sync.Mutex
)一起使用,以确保条件检查和条件变量的等待/通知操作是原子的。sync.Cond
的 Wait
方法用于阻塞调用它的goroutine,直到另一个goroutine调用 Signal
或 Broadcast
方法。
使用 sync.Cond
的 Wait
方法
在使用 sync.Cond
的 Wait
方法时,你首先需要确保 sync.Cond
是与某个互斥锁(比如 sync.Mutex
)关联的。在调用 Wait
方法之前,必须先加锁,并且在 Wait
方法内部,锁会被自动释放并在等待的goroutine被唤醒时重新获取。
下面是一个简单的示例,展示了如何在Go语言中使用 sync.Cond
的 Wait
方法:
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
时需要特别注意锁的管理,确保在正确的时机加锁和解锁,以避免竞态条件和其他并发问题。