sync.WaitGroup waits for a collection of goroutines to finish. 类似一个计数器,添加任务加一,完成任务减一,非零即阻塞。

  • Add(x) 添加到计数器,需要注意的是必须在 main goroutine 执行
  • Done() 计数器减一
  • Wait() 阻塞 main goroutine 执行,直到所有 goroutine 执行完成。
var wg sync.WaitGroup
var urls = []string{
    "http://www.google.com/",
    "http://fann.im/",
}
var errChan = make(chan error, len(urls))

for _, url := range urls {
    wg.Add(1)

    go func(url string) {
        defer wg.Done()

        resp, err := http.Get(url)
        if err != nil {
            errChan <- err
        }
        defer resp.Body.Close()
    }(url)
}

wg.Wait()
close(errChan)

for err := range errChan {
    if err != nil {
        log.Println(err.Error())
    }
}