当前位置: 首页 > 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
}()

相关文章:

  • LM2902:一款高性能四运算放大器的解析
  • 蓝桥杯 2024 C++国 B最小字符串
  • 论文学习_Directed Greybox Fuzzing
  • 《MySQL:MySQL视图特性》
  • rsync入门笔记
  • 第30节:现代CNN架构-轻量级架构EfficientNet
  • 【YOLO 系列】基于YOLO的道路坑洞检测识别系统【python源码+Pyqt5界面+数据集+训练代码】
  • 各个历史版本mysql/tomcat/Redis/Jdk/Apache下载地址
  • 解决facefusion下载抱错的问题
  • ADS1220高精度ADC(TI)——应用 源码
  • 科学养生指南:解锁健康生活的密码
  • 【Python】【面试凉经】Fastapi为什么Fast
  • 第一天的尝试
  • iOS性能调优实践:我常用的工具与流程(含克魔 KeyMob 使用体验)
  • 【在qiankun模式下el-dropdown点击,浏览器报Failed to execute ‘getComputedStyle‘ on ‘Window‘: parameter 1 is not o
  • 矫平机深度解析:技术细节、行业应用与未来革新
  • set, multiset ,unordered_set; map, multimap, unordered_map
  • 本地部署Firecrawl+Dify调用踩坑记录
  • MySQL 8.0 OCP 1Z0-908 101-110题
  • C++delete详解剖析
  • 涉案资金超2亿元 “健康投资”骗局,专挑老年人下手
  • “85后”贵阳市政府驻重庆办事处主任吴育材拟任新职
  • 1至4月全国铁路发送旅客14.6亿人次,创同期历史新高
  • 陕西宁强县委书记李宽任汉中市副市长
  • 2025财政观察|长三角“三公”经费普降,钱要用在刀刃上
  • 在稳市场稳预期下,投资者教育给了散户更多底气