Go语言并发编程中 Broadcast 和 Signal 区别
Go语言并发编程中 Broadcast 和 Signal 区别
func (c *Cond) Broadcast()
Broadcast 会唤醒所有等待 c 的 goroutine。 调用 Broadcast 的时候,可以加锁,也可以不加锁。
func (c *Cond) Signal()
Signal 只唤醒 1 个等待 c 的 goroutine。 调用 Signal 的时候,可以加锁,也可以不加锁。
在Go语言的并发编程中,Broadcast
和 Signal
这两个概念并不是Go标准库直接提供的同步机制,它们通常与某些同步原语(如通道channel
、sync
包中的条件变量等)的使用模式相关联,用于在多goroutine之间协调操作。不过,我们可以通过这些概念来理解如何在Go中实现类似的功能。
Broadcast(广播)
在Go中,Broadcast
通常指的是一个事件或信号被发送给多个监听者(goroutines)。一个常见的实现方式是使用channel
和close
操作来模拟广播机制,或者使用sync.WaitGroup
配合多个channel
来实现更复杂的逻辑。
示例代码(使用close模拟Broadcast):
package main
import (
"fmt"
"sync"
"time"
)
func broadcaster(done chan bool, msg string) {
// 模拟耗时操作
time.Sleep(2 * time.Second)
close(done) // 广播完成信号
fmt.Println("Broadcast:", msg)
}
func listener(id int, done chan bool) {
<-done // 等待接收广播
fmt.Printf("Listener %d received the broadcast\n", id)
}
func main() {
var wg sync.WaitGroup
done := make(chan bool)
// 启动广播者
go broadcaster(done, "Hello, Goroutines!")
// 启动多个监听者
for i := 1; i <= 5; i++ {
wg.Add(1)
go func(id int) {
defer wg.Done()
listener(id, done)
}(i)
}
wg.Wait() // 等待所有监听者完成
}
注意:这里使用close(done)
来模拟广播完成,但实际上这更多是一种“完成”信号的广播,而不是真正的数据广播。
Signal(信号)
在Go中,Signal
指的是向一个或多个监听者发送特定的通知或数据。这通常通过channel
直接发送数据来实现。
示例代码(使用channel发送Signal):
package main
import (
"fmt"
"time"
)
func signaler(signal chan<- string) {
// 模拟耗时操作
time.Sleep(1 * time.Second)
signal <- "Action completed!" // 发送信号
}
func listener(signal <-chan string) {
msg := <-signal // 接收信号
fmt.Println("Received signal:", msg)
}
func main() {
signal := make(chan string)
// 启动信号发送者
go signaler(signal)
// 启动监听者
go listener(signal)
// 注意:在这个简单示例中,main函数会直接退出,可能看不到listener的输出。
// 在实际应用中,你可能需要等待listener完成或使用其他同步机制。
// 这里仅为演示信号发送。
// 等待信号发送者完成(仅为示例,实际应用中可能不需要)
time.Sleep(2 * time.Second)
}
总结,Broadcast
和 Signal
在Go中主要通过channel
来模拟实现,Broadcast
通常涉及到向多个监听者发送相同的事件或完成信号,而Signal
则是向特定监听者发送具体的消息或通知。