答案: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{}) // 用于通知的 channel
go func() {
// 模拟耗时操作
time.Sleep(2 * time.Second)
done <- struct{}{} // 发送完成信号
}()
// 主协程阻塞等待
<-done
fmt.Println("任务已完成")
使用带缓冲 channel 实现多次通知
当需要通知多个事件或多个协程时,可以使用带缓冲的 channel 避免阻塞。
常见场景:多个 worker 协程完成任务后向同一个 channel 发送完成信号。
workers := 5 notify := 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 实现。
华友协同办公管理系统(华友OA),基于微软最新的.net 2.0平台和SQL Server数据库,集成强大的Ajax技术,采用多层分布式架构,实现统一办公平台,功能强大、价格便宜,是适用于企事业单位的通用型网络协同办公系统。 系统秉承协同办公的思想,集成即时通讯、日记管理、通知管理、邮件管理、新闻、考勤管理、短信管理、个人文件柜、日程安排、工作计划、工作日清、通讯录、公文流转、论坛、在线调查、
立即学习“go语言免费学习笔记(深入)”;
示例:一个长时间运行的协程监听取消信号:
ctx, cancel := context.WithCancel(context.Background())go func(ctx context.Context) { for { select { case <-ctx.Done(): fmt.Println("收到取消通知") return default: // 执行周期性任务 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.Mutex cond := sync.NewCond(&mu) ready := falsego func() { time.Sleep(2 * time.Second) mu.Lock() ready = true mu.Unlock() cond.Broadcast() // 通知所有等待者 }()
mu.Lock() for !ready { cond.Wait() // 等待通知 } mu.Unlock() fmt.Println("条件已满足")
基本上就这些。最常用的是 channel 和 context 配合使用,简单、清晰且符合 Go 的并发哲学。根据具体需求选择合适的方式即可。不复杂但容易忽略细节,比如 channel 类型的选择和是否带缓冲。









