WaitGroup如何其中一个协程发生错误,应该如何处理

  等待一个协程组全部正确完成则结束;但其中一个协程发生错误,这时候就会阻塞,全部停止运行(本次任务失败)以免浪费系统资源,此时可以结合通道(channel)或者 select 语句两种方式来处理。

1、考虑使用两个通道:一个用于报告错误,另一个用于通知所有协程停止。在协程内部捕获错误,并将错误信息发送到错误通道。另一个协程监听错误通道,一旦有错误发生,就会向停止通知通道发送信号,通知所有协程停止运行。

复制代码
package main

import (
    "fmt"
    "sync"
)

func worker(id int, errCh chan error, wg *sync.WaitGroup) {
    defer wg.Done()

    // 模拟错误
    if id == 2 {
        errCh <- fmt.Errorf("error occurred in worker %d", id)
        return
    }

    // 做一些工作
    fmt.Printf("Worker %d is working...\n", id)
}

func main() {
    var wg sync.WaitGroup
    errCh := make(chan error)
    stopCh := make(chan struct{})

    for i := 0; i < 5; i++ {
        wg.Add(1)
        go worker(i, errCh, &wg)
    }

    go func() {
        err := <-errCh
        if err != nil {
            fmt.Println("Error occurred:", err)
            close(stopCh)
        }
    }()

    go func() {
        wg.Wait()
        close(errCh)
    }()

    // 等待通知,停止所有协程
    <-stopCh
    fmt.Println("All workers stopped.")
}
复制代码

errCh 通道用于发送错误信息,stopCh 通道用于通知所有协程停止。如果有一个协程发生错误,就会关闭 stopCh 通道,通知其他协程停止运行。

2、select 语句是 Go 中用于多路非阻塞的关键字,可以用于监听多个通道的操作。可以在 select 语句中组合使用 WaitGroup 和通道来实现对协程组的控制。

复制代码
package main

import (
    "fmt"
    "sync"
)

func worker(id int, errCh chan error, wg *sync.WaitGroup) {
    defer wg.Done()

    // 模拟错误
    if id == 2 {
        errCh <- fmt.Errorf("error occurred in worker %d", id)
        return
    }

    // 做一些工作
    fmt.Printf("Worker %d is working...\n", id)
}

func main() {
    var wg sync.WaitGroup
    errCh := make(chan error)

    for i := 0; i < 5; i++ {
        wg.Add(1)
        go worker(i, errCh, &wg)
    }

    go func() {
        wg.Wait()
        close(errCh)
    }()

    for {
        select {
        case err, ok := <-errCh:
            if ok {
                fmt.Println("Error occurred:", err)
                // 处理错误,根据需要执行相关操作
            } else {
                fmt.Println("All workers completed successfully.")
                return
            }
        }
    }
}
复制代码

 select 语句监听 errCh 通道,等待错误消息。当收到错误消息时,可以根据需要执行相应的错误处理。当 errCh 通道关闭时,ok 的值为 false,表示所有协程已经成功完成。

posted @   李若盛开  阅读(88)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· DeepSeek 开源周回顾「GitHub 热点速览」
点击右上角即可分享
微信分享提示