答案:Go中多协程通知主要通过channel和context实现。使用无缓冲channel可实现同步信号传递,如主协程等待子协程完成;带缓冲channel适用于多个worker完成通知;context用于取消或超时控制,结合select监听Done通道;sync.Cond则用于共享变量状态变化的条件通知。最常用的是channel与context配合,需注意缓冲选择和类型细节。

在Go语言中,多协程之间的事件通知通常通过 channel 来实现。channel 是 Go 并发编程的核心机制,既能传递数据,也能用于协程间的同步与通知。以下是几种常见的实现方式。
使用无缓冲 channel 进行信号通知
无缓冲 channel 可以实现协程间的同步等待。发送方发送通知后,接收方收到信号继续执行。
例如:
主协程等待子协程完成任务:
创建一个无缓冲 channel,在子协程完成时发送一个 signal,主协程通过接收该 signal 确认任务结束。
done := make(chan struct{}) // 用于通知的 channelgo func() {// 模拟耗时操作time.Sleep(2 * time.Second)done <- struct{}{} // 发送完成信号}()
// 主协程阻塞等待<-donefmt.Println("任务已完成")
使用带缓冲 channel 实现多次通知
当需要通知多个事件或多个协程时,可以使用带缓冲的 channel 避免阻塞。
常见场景:
多个 worker 协程完成任务后向同一个 channel 发送完成信号。
workers := 5notify := make(chan bool, workers)for i := 0; i < workers; i++ {go func() {// 模拟工作time.Sleep(time.Millisecond * 100)notify <- true // 完成即发送}()}
// 等待所有 worker 完成for i := 0; i < workers; i++ {<-notify}fmt.Println("所有任务完成")
使用 context 控制协程生命周期
对于更复杂的场景,比如取消通知或超时控制,推荐使用 context 结合 channel 实现。
立即学习“go语言免费学习笔记(深入)”;
示例:
一个长时间运行的协程监听取消信号:
ctx, cancel := context.WithCancel(context.Background())go func(ctx context.Context) {for {select {case <-ctx.Done():fmt.Println("收到取消通知")returndefault:// 执行周期性任务time.Sleep(500 * time.Millisecond)}}}(ctx)
// 某些条件下触发取消time.Sleep(2 * time.Second)cancel() // 发送取消信号
time.Sleep(100 * time.Millisecond) // 等待退出
使用 sync.Cond 实现条件通知(较少用)
在某些共享变量状态变化需要通知多个协程时,可使用 sync.Cond。
它适用于多个 goroutine 等待某个条件成立的场景,比如“等待队列非空”。
var mu sync.Mutexcond := sync.NewCond(&mu)ready := falsego func() {time.Sleep(2 * time.Second)mu.Lock()ready = truemu.Unlock()cond.Broadcast() // 通知所有等待者}()
mu.Lock()for !ready {cond.Wait() // 等待通知}mu.Unlock()fmt.Println("条件已满足")
基本上就这些。最常用的是 channel 和 context 配合使用,简单、清晰且符合 Go 的并发哲学。根据具体需求选择合适的方式即可。不复杂但容易忽略细节,比如 channel 类型的选择和是否带缓冲。
以上就是Golang如何在多协程中实现事件通知的详细内容,更多请关注创想鸟其它相关文章!
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1410403.html
微信扫一扫
支付宝扫一扫