go基础库errgroup

28 阅读1分钟

errgroup 是 Go 编程语言中的一个并发模式库,属于 golang.org/x/sync 包的一部分。它被广泛用于管理一组 goroutine 的并发执行,并简化错误处理。

errgroup 的主要作用包括:

  1. 并发管理: errgroup 可以同时启动多个 goroutine,并等待所有 goroutine 执行完成。这样可以方便地管理并发任务。
  2. 错误处理: 在使用 errgroup 时,如果其中任何一个 goroutine 返回错误,errgroup 会捕获这个错误并返回,从而简化了错误处理逻辑。
  3. 上下文取消: errgroup 支持与 context 包一起使用。当一个 goroutine 返回错误时,errgroup 可以取消所有其他 goroutine 的执行,避免不必要的计算和资源浪费。

一个简单的例子可以帮助理解 errgroup 的使用:


package main

import (
    "context"
    "fmt"
    "golang.org/x/sync/errgroup"
    "net/http"
)

func main() {
    // 创建一个 errgroup 和一个带有取消功能的上下文
    g, ctx := errgroup.WithContext(context.Background())

    urls := []string{
       "http://example.com",
       //"http://example11111.com",
       "http://example.net",
       "http://example.org",
    }

    for _, url := range urls {
       // 启动一个 goroutine 来抓取每个 URL
       url := url // 创建一个新的变量以避免闭包问题
       g.Go(func() error {
          // 使用 ctx 发起 HTTP 请求
          req, err := http.NewRequestWithContext(ctx, "GET", url, nil)
          if err != nil {
             return err
          }

          resp, err := http.DefaultClient.Do(req)
          if err != nil {
             return err
          }
          defer resp.Body.Close()

          if resp.StatusCode != http.StatusOK {
             return fmt.Errorf("error fetching %s: %s", url, resp.Status)
          }

          fmt.Printf("Successfully fetched %s\n", url)
          return nil
       })
    }

    // 等待所有的 goroutine 完成
    if err := g.Wait(); err != nil {
       fmt.Printf("Error: %v\n", err)
    } else {
       fmt.Println("All URLs fetched successfully.")
    }
}

使用正确地址全部成功 image.png 使用错误地址,返回错误,取消其他goroutine image.png