当前位置: 首页 > news >正文

Go语言中的条件变量:sync.NewCond

在并发编程中,我们经常需要在多个goroutine之间同步操作,特别是当某些操作需要等待特定条件发生时。Go语言的sync包提供了一个强大的同步原语——条件变量(Cond),它允许我们等待或通知某个条件的变化。

sync.NewCond

sync.NewCond函数用于创建一个新的条件变量,并将其与一个互斥锁(sync.Mutexsync.RWMutex)关联。这个条件变量可以用来挂起和唤醒goroutine,以便在满足特定条件时协调它们的执行。

条件变量的方法

  • L:条件变量关联的互斥锁。
  • Wait():当前goroutine在调用此方法后会被挂起,直到被SignalBroadcast唤醒。
  • Signal():唤醒一个等待条件变量的goroutine(如果有的话)。
  • Broadcast():唤醒所有等待条件变量的goroutine。

示例代码

下面是一个使用sync.NewCond的示例,模拟了一个比赛场景,其中10个选手需要等待一个开始信号才能开始比赛。

package mainimport ("fmt""sync""time"
)func main() {race()
}// race 函数模拟了一个比赛场景,10个选手等待一个信号开始比赛
func race() {// 创建一个条件变量和互斥锁cond := sync.NewCond(&sync.Mutex{})// 创建一个等待组,用于等待所有选手完成比赛var wg sync.WaitGroup// 初始化等待组,添加11个任务(10个选手 + 1个发令员)wg.Add(11)// 启动10个选手的goroutinefor i := 0; i < 10; i++ {go func(num int) {// 选手完成后,将等待组计数器减一defer wg.Done()// 打印选手就位信息fmt.Println(num, "号已经就位")// 选手获取互斥锁,准备等待信号cond.L.Lock()// 选手等待条件变量的信号cond.Wait()// 打印选手开始工作的信息fmt.Println(num, "号已开始工作")// 选手释放互斥锁cond.L.Unlock()}(i)}// 等待2秒,模拟比赛准备时间time.Sleep(2 * time.Second)// 启动一个goroutine,用于发送比赛开始的信号go func() {// 完成后,将等待组计数器减一defer wg.Done()// 打印准备开始的信息fmt.Println("准备开始!")// 发送广播信号,通知所有等待的选手开始比赛cond.Broadcast()}()// 等待所有选手完成比赛wg.Wait()
}

工作原理

在这个示例中,我们首先创建了一个条件变量cond,并将其与一个新的sync.Mutex关联。然后,我们启动了10个goroutine来模拟选手,每个选手在就位后会调用cond.Wait()来挂起自己。这会导致它们释放互斥锁并等待信号。

主goroutine等待2秒钟后,启动一个发令员goroutine,它调用cond.Broadcast()来唤醒所有等待的选手。当选手们被唤醒后,它们会重新获取互斥锁,打印开始工作的信息,然后释放互斥锁。

应用场景

条件变量非常适合用于需要等待特定事件或条件发生的场景,例如:

  • 生产者-消费者问题,消费者等待生产者生产数据。
  • 信号量控制,限制同时访问某个资源的goroutine数量。
  • 任何需要在多个goroutine之间同步执行的场景。

总结

sync.NewCond是Go语言中一个非常实用的同步原语,它提供了一种简单而有效的方式来协调多个goroutine的执行。通过使用条件变量,我们可以编写出更加灵活和高效的并发程序。在处理复杂的并发问题时,sync.NewCond是一个不可或缺的工具。


http://www.mrgr.cn/news/77733.html

相关文章:

  • 《新闻大厦抢先版》V0.18.105+Dlcs官方学习版
  • notebook主目录及pip镜像源修改
  • 【数据库系统概论】第5章 数据库完整性【!触发器】
  • 阿里mod_asr3.0集成webrtc静音算法
  • 深入探索AI核心模型:CNN、RNN、GAN与Transformer
  • (2024,影响 LLaVA 性能的因素,LLM 模型规模,视觉输入配置(网格/token 数),AnyRes,数据量/质量)
  • 【数据库入门】关系型数据库入门及SQL语句的编写
  • 封装实现通用的 `forEach` 函数:深入JavaScript的迭代机制与细节优化
  • 历遍单片机下的IIC设备[ESP--0]
  • 配置Springboot+vue项目在ubuntu20.04
  • docker-compose快速编排docker容器
  • 如何使用 ChatGPT 进行关键字研究
  • 对 TypeScript 中类是怎么理解的?都有哪些应用场景?
  • Vue 如何简单更快的对 TypeScript 中接口的理解?应用场景?
  • 使用Mac下载MySQL修改密码
  • vscode 远程连接ssh 密钥方式
  • Python 神经网络项目常用语法
  • 葡萄酒(wine)数据集——LDA、贝叶斯判别分析
  • 力扣整理版八:回溯算法(待更新)
  • ReactPress vs VuePress vs WordPress
  • Java进阶五 -IO流
  • 【代码随想录day36】【C++复健】1049. 最后一块石头的重量 II ; 494. 目标和 ;474.一和零
  • 大语言模型---LoRA简介;LoRA的优势;LoRA训练步骤;总结
  • 大语言模型---ReLU函数的计算过程及其函数介绍
  • 计算机网络实验
  • 【Oracle实战】文章导读