package main
import (
"fmt"
"sync"
)
func main() {
var wg sync.WaitGroup
// 假设启动3个goroutine
wg.Add(3)
// 用于通知主程序异常的通道
errCh := make(chan error)
for i := 0; i < 3; i++ {
go func(id int) {
defer wg.Done()
// 模拟任务,这里简单判断id为1时出现异常
if id == 1 {
errCh <- fmt.Errorf("goroutine %d failed", id)
return
}
fmt.Printf("goroutine %d finished\n", id)
}(i)
}
go func() {
wg.Wait()
close(errCh)
}()
for err := range errCh {
if err != nil {
fmt.Println("Caught error:", err)
}
}
}
简要说明
- WaitGroup计数:在启动每个goroutine前调用
wg.Add(1)
增加计数,在每个goroutine结束前调用wg.Done()
减少计数。
- 异常通知:
- 创建一个
error
类型的通道errCh
,用于传递异常信息。
- 在可能出现异常的goroutine中,当异常发生时,通过
errCh
发送异常信息。
- 主程序通过遍历
errCh
通道来获取异常信息,如果接收到非空的error
,则表示有goroutine出现异常。
- 使用一个额外的goroutine等待所有goroutine完成(
wg.Wait()
),完成后关闭errCh
通道,这样主程序的for... range
循环可以正常结束。