在 Go 语言中,sync 包提供了多种用于并发控制的工具。其中,sync.Cond 是一个相对少用但功能强大的条件变量同步原语。本文将带你从零开始,深入理解 Go语言 sync.Cond 的 Signal 唤醒机制,即使是并发编程的新手也能轻松掌握。
sync.Cond 是 Go 语言标准库中的条件变量(Condition Variable),它允许一组 goroutine 在某个条件满足前等待,并在条件变化时被唤醒。它通常与互斥锁(sync.Mutex 或 sync.RWMutex)配合使用。
条件变量的核心方法包括:
Wait():使当前 goroutine 进入等待状态,直到被唤醒。Signal():唤醒一个等待中的 goroutine。Broadcast():唤醒所有等待中的 goroutine。
在多个 goroutine 等待同一个条件时,Signal() 方法只会唤醒其中一个等待的 goroutine。这与 Broadcast() 不同,后者会唤醒全部。
这种“一对一”唤醒机制非常适合生产者-消费者模型、任务调度等场景,避免不必要的资源竞争和上下文切换。
下面是一个简单的例子:一个生产者 goroutine 每隔 2 秒生成一个任务,并通过 Signal() 唤醒一个等待的消费者。
package mainimport ( "fmt" "sync" "time")func main() { var mu sync.Mutex cond := sync.NewCond(&mu) taskQueue := make([]int, 0) // 启动 3 个消费者 for i := 1; i <= 3; i++ { go func(id int) { for { mu.Lock() // 如果队列为空,等待信号 for len(taskQueue) == 0 { cond.Wait() } // 取出任务 task := taskQueue[0] taskQueue = taskQueue[1:] mu.Unlock() fmt.Printf("消费者 %d 处理任务 %d\n", id, task) time.Sleep(1 * time.Second) // 模拟处理时间 } }(i) } // 生产者:每 2 秒添加一个任务并 Signal 唤醒一个消费者 taskID := 1 for { time.Sleep(2 * time.Second) mu.Lock() taskQueue = append(taskQueue, taskID) fmt.Printf("生产者添加任务 %d\n", taskID) cond.Signal() // 👈 关键:只唤醒一个等待的消费者 mu.Unlock() taskID++ }}在这个例子中:
taskQueue,由互斥锁 mu 保护。cond.Wait() 进入等待状态(此时会自动释放锁)。cond.Signal() 唤醒一个正在等待的消费者。运行程序,你会看到每次只有一位消费者被唤醒处理任务,体现了 Signal 唤醒机制 的精准控制。
Wait()、Signal() 前必须持有对应的锁。for 循环中检查条件,而不是 if。Signal();若需通知所有等待者(如配置更新),才使用 Broadcast()。通过本文,你已经掌握了 Go语言 中 sync.Cond 的核心用法,特别是 Signal() 的唤醒机制。它是一种高效、精确的 goroutine 通信方式,适用于需要按需唤醒特定协程的并发场景。
记住:合理使用 sync.Cond 能让你的 Go 并发程序更高效、更可控。希望这篇教程能帮助你深入理解这一强大工具!
关键词回顾:Go语言、sync.Cond、Signal、唤醒机制。
本文由主机测评网于2025-12-17发表在主机测评网_免费VPS_免费云服务器_免费独立服务器,如有疑问,请联系我们。
本文链接:https://www.vpshk.cn/2025129020.html