MST

星途 面试题库

面试题:Go WaitGroup异常处理场景

假设在使用WaitGroup等待一组goroutine完成任务时,其中一个goroutine由于某种原因(如网络请求失败等)需要提前结束并通知主程序,在这种情况下如何处理WaitGroup的计数以及主程序如何得知该异常?请给出代码示例及简要说明。
37.6万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试
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)
        }
    }
}

简要说明

  1. WaitGroup计数:在启动每个goroutine前调用wg.Add(1)增加计数,在每个goroutine结束前调用wg.Done()减少计数。
  2. 异常通知
    • 创建一个error类型的通道errCh,用于传递异常信息。
    • 在可能出现异常的goroutine中,当异常发生时,通过errCh发送异常信息。
    • 主程序通过遍历errCh通道来获取异常信息,如果接收到非空的error,则表示有goroutine出现异常。
    • 使用一个额外的goroutine等待所有goroutine完成(wg.Wait()),完成后关闭errCh通道,这样主程序的for... range循环可以正常结束。