sync.WaitGroup 是 Golang 标准库中 sync 包提供的一个非常实用的同步机制,主要用于等待一组协程(goroutines)的执行结束。
sync.WaitGroup 的核心作用是用来等待一组协程的执行完成。它可以确保主协程在所有其他协程执行完毕之前不会退出。这对于管理并发任务非常有帮助,特别是当你无法确定具体要启动多少个协程,或者这些协程之间有复杂的依赖关系时。
具体来说,sync.WaitGroup 提供了以下几个方法:
Add(delta int):用来设置需要等待的协程数量。delta可以是正数也可以是负数,表示增加或减少等待协程的数量。Done():当协程完成它的任务后,调用此方法来通知 WaitGroup 对象一个协程已经完成了,内部实际上是调用了Add(-1)。Wait():调用此方法会阻塞当前协程,直到 WaitGroup 中的所有协程都调用了Done()方法,即协程数量归零。
示例用法
来看一个具体的例子,假设我们需要并发地完成多个HTTP请求,我们可以使用 sync.WaitGroup 来等待所有请求处理完毕:
gopackage main import ( "net/http" "sync" "fmt" ) func main() { var wg sync.WaitGroup urls := []string{ "http://www.google.com", "http://www.facebook.com", "http://www.baidu.com", } for _, url := range urls { // 每启动一个协程,计数器增加 1 wg.Add(1) go func(url string) { defer wg.Done() // 确保协程完成后计数器减 1 _, err := http.Get(url) if err != nil { fmt.Println(err) return } fmt.Println("Fetched", url) }(url) } // 等待所有请求完成 wg.Wait() fmt.Println("All requests are done!") }
在这个例子中,我们并发地发起了多个HTTP请求,每个请求是在一个独立的协程中执行的。我们使用 wg.Add(1) 来表示有一个新的任务开始,而在每个协程的末尾使用 defer wg.Done() 来表示该任务完成。主协程中的 wg.Wait() 会阻塞,直到所有子协程都执行了 Done() 方法,即所有 HTTP 请求都处理完毕后,程序才会继续执行并打印出 "All requests are done!"。
通过使用 sync.WaitGroup,我们能够有效地管理和同步复杂的并发逻辑,保证程序的正确执行和资源的合理利用。
2024年10月26日 16:54 回复