Golang 同步工具 方法及使用示例 Sync.Cond
sync.Cond
sync.Cond 是一类基于 Golang 标准库提供的互斥/读写锁实现的条件变量,用于协调访问共同共享资源。多个goroutine。当共享资源的状态发生变化时,可以通知阻塞等待条件变化的goroutine。 sync.Cond提供了一个create方法和三个成员方法,如下:
- NewCond(l Locker)。创建Cond对象,必须传入锁对象,互斥锁或者读写锁;
- Wait() ,立即屏蔽goroutine并等待消息信号;
- Signal(),发送信号通知,唤醒等待中的goroutine;
- Broadcast(),发送信号消息,唤醒goroutine等待的人群。
sync.Cond 必须与互斥锁或读写锁一起使用,以确保共享资源不会被并发操作。当处于锁定状态时,程序将阻塞在Wait()方法中,直到另一个程序通过Broadcast()和Signal()方法发送通知信号。
方法及使用示例
特殊使用方法如下:
创建 Mutex 对象
var mutex = sync.Mutex{}
创建 Cond 对象,进入 Mutex
cond := sync.NewCond(&mutex)
现在等待 goroutine 的通知信号
cond.Wait()
发送通知信号,唤醒一个或多个正在等待的goroutine
cond.Signal() // 唤醒一个goroutine
// 或者 cond.Broadcast() 唤醒多个goroutine
看例子:
package main
import (
"log"
"sync"
"time"
)
func read(index int, c *sync.Cond) {
c.L.Lock()
c.Wait()
log.Println(index, "开始读")
c.L.Unlock()
}
func write(c *sync.Cond) {
log.Println("开始写")
time.Sleep(time.Second)
log.Println("唤醒其中一个goroutine")
c.Signal()
}
func main() {
cond := sync.NewCond(&sync.Mutex{})
for i := 1; i <= 5; i++ {
go func(index int) {
read(index, cond)
}(i)
}
write(cond)
time.Sleep(time.Second * 3)
}
输出内容如下:
2023/05/19 22:01:34 开始写
2023/05/19 22:01:35 唤醒其中一个goroutine
2023/05/19 22:01:35 2 开始读
可以看出,Signal()方法只唤醒了一个或多个goroutine,而二十行可以改成c.Broadcast(),打开看效果,你会发现所有goroutine都被唤醒了。
总结
sync.Cond在基本机制的基础上开发了一个通知等待列表,当goroutine等待通知时将其添加到通知等待列表中,然后通过Signal()或Broadcast()发送通知信号)方法唤醒goroutine等待列表,实现与goroutine的通信和条件变量同步。
使用sync.Cond可以使并发程序更加高效和灵活,避免使用time.Sleep()或空for循环的一些弊端。不过,条件变量的使用也应该谨慎使用,避免出现死锁和竞争条件等问题。
版权声明
本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。
发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。