面试题答案
一键面试可以使用 sync.WaitGroup
来等待所有 Goroutine 完成,并使用一个 chan
来收集错误。以下是示例代码:
package main
import (
"fmt"
"sync"
)
func worker(id int, wg *sync.WaitGroup, errChan chan error) {
defer wg.Done()
// 模拟可能返回错误的任务
if id == 2 {
errChan <- fmt.Errorf("worker %d failed", id)
return
}
fmt.Printf("worker %d completed\n", id)
errChan <- nil
}
func main() {
var wg sync.WaitGroup
errChan := make(chan error)
numWorkers := 3
for i := 1; i <= numWorkers; i++ {
wg.Add(1)
go worker(i, &wg, errChan)
}
go func() {
wg.Wait()
close(errChan)
}()
var errors []error
for err := range errChan {
if err != nil {
errors = append(errors, err)
}
}
if len(errors) > 0 {
fmt.Println("Encountered errors:")
for _, err := range errors {
fmt.Println(err)
}
} else {
fmt.Println("All workers completed successfully")
}
}
代码解释
worker
函数:每个 Goroutine 执行此函数,它接收一个id
、WaitGroup
指针和一个errChan
。函数结束时调用wg.Done()
通知WaitGroup
该 Goroutine 已完成。这里模拟了一种可能出错的情况,如果id
为2,则返回错误。main
函数:- 初始化
WaitGroup
和errChan
。 - 启动多个 Goroutine 并添加到
WaitGroup
中。 - 另一个 Goroutine 等待所有 Goroutine 完成后关闭
errChan
。 - 通过
for... range
从errChan
中读取错误,并将非空错误收集到errors
切片中。 - 最后根据
errors
切片的长度判断是否所有任务都成功完成,并输出相应信息。
- 初始化