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

Golang基础知识—cond

cond 通常指 sync.Cond,它是标准库 sync 包中用于实现 条件变量 的同步原语。条件变量在多 goroutine 协作场景中非常有用,尤其在需要根据特定条件协调多个 goroutine 的执行顺序时。


sync.Cond 的核心作用

条件变量用于 等待某个条件满足 或 通知其他等待者条件已满足。常用于以下场景:

  • 一个或多个 goroutine 需要等待某个条件成立才能继续执行。

  • 某个 goroutine 负责修改条件,并通知其他等待的 goroutine。


sync.Cond 的组成

type Cond struct {L Locker // 关联的锁(通常是 sync.Mutex 或 sync.RWMutex)
}

主要方法:

  1. Wait()

    • 调用前必须持有锁(c.L.Lock())。

    • 释放锁并挂起当前 goroutine,等待被唤醒。

    • 被唤醒后重新获取锁,继续执行。

  2. Signal()

    • 唤醒一个等待的 goroutine(随机选择一个)。

  3. Broadcast()

    • 唤醒所有等待的 goroutine。


基本使用模式

var (mu    sync.Mutexcond  = sync.NewCond(&mu)ready bool
)// 等待条件满足的 goroutine
func waiter() {mu.Lock()defer mu.Unlock()for !ready { // 必须用循环检查条件(防止虚假唤醒)cond.Wait()}// 执行条件满足后的操作
}// 修改条件并通知的 goroutine
func setter() {mu.Lock()ready = truemu.Unlock()cond.Signal() // 或 cond.Broadcast()
}
 

经典示例:生产者-消费者

package mainimport ("fmt""sync""time"
)func main() {var mu sync.Mutexcond := sync.NewCond(&mu)queue := make([]int, 0)// 消费者go func() {for {mu.Lock()for len(queue) == 0 {cond.Wait() // 等待队列非空}item := queue[0]queue = queue[1:]fmt.Println("Consumed:", item)mu.Unlock()}}()// 生产者for i := 1; i <= 5; i++ {time.Sleep(1 * time.Second)mu.Lock()queue = append(queue, i)fmt.Println("Produced:", i)cond.Signal() // 通知消费者mu.Unlock()}
}

关键注意事项

  1. 必须用循环检查条件
    Wait() 返回后条件可能仍未满足(如虚假唤醒),需循环检查:

    for conditionNotMet {cond.Wait()
    }
  2. 调用 Wait() 前必须持有锁
    否则会导致竞态条件。

  3. Signal vs Broadcast

    • Signal:唤醒一个等待者(适用于单消费者)。

    • Broadcast:唤醒所有等待者(适用于多消费者或条件变化影响所有等待者)。


何时使用 sync.Cond

  • 需要 基于复杂条件协调多个 goroutine

  • 需要 同时唤醒多个等待者(如资源释放时唤醒所有等待的 goroutine)。

对于简单场景,优先考虑使用 channel(Go 的推荐并发模式):

// 用 channel 实现类似功能
ch := make(chan int)// 生产者
go func() {ch <- 1
}()// 消费者
go func() {item := <-ch
}()

http://www.xdnf.cn/news/456751.html

相关文章:

  • 51c~C语言~合集5
  • Python Bug 修复案例分析:asyncio 事件循环异常引发的程序崩溃 两种修复方法
  • 深度解析 IDEA 集成 Continue 插件:提升开发效率的全流程指南
  • 2025长三角杯数学建模A题:智能手机产品设计优化与定价问题,赛题发布与思路分析
  • 2025.05.14华为机考笔试题-第一题-100分
  • 边缘计算模块
  • 解密企业级大模型智能体Agentic AI 关键技术:MCP、A2A、Reasoning LLMs-docker MCP解析
  • 开源GPU架构RISC-V VCIX的深度学习潜力测试:从RTL仿真到MNIST实战
  • 1、数据结构与算法(Python版-啃书)-绪论
  • CodeEdit:macOS上一款可以让Xcode退休的IDE
  • React 第四十一节Router 中 useActionData 使用方法案例以及注意事项
  • SQL笔记一
  • C#.NET 或 VB.NET Windows 窗体中的 DataGridView – 技巧、窍门和常见问题
  • 资产管理系统评测:功能、易用性、性价比全面对比
  • [C++面试] lambda面试点
  • 使用gitbook 工具编写接口文档或博客
  • AWS EC2 微服务 金丝雀发布(Canary Release)方案
  • 使用WebSocket实现跨多个服务器传输音频及实时语音识别
  • Linux线程控制
  • 2025年5月华为H12-821新增题库带解析
  • 阿里云CMH镜像迁移与SMC整机迁移对比及功能详解(同地域跨主体账号场景)
  • Elasticsearch相关面试题
  • MUSE Pi Pro 使用TiTanTools烧录镜像
  • 华为2024年报:鸿蒙生态正在取得历史性突破
  • C 语言实战:使用二维数组进行学生成绩统计与分析
  • React Native简介
  • 机器学习中采样哪些事
  • 牛客网NC22157:牛牛学数列2
  • RPC与SOAP的区别
  • C语言-8.数组