在Go语言中,goroutine是非常常见和重要的概念。它们允许我们将任务并行化,从而提高程序的性能。有时我们需要等待一组goroutine完成后再执行下一步操作,这时候就可以使用sync.WaitGroup。
sync.WaitGroup是Go语言标准库中的一个同步原语,它可以让主线程等待一组goroutine的执行完毕。具体来说,我们可以通过如下三个方法来使用sync.WaitGroup:
- Add(delta int):向WaitGroup中添加或减少计数器的值。delta可以为正数或负数,正数表示添加计数器的值,负数表示减少计数器的值。
- Done():减少WaitGroup中计数器的值,相当于Add(-1)。
- Wait():阻塞调用它的goroutine,直到WaitGroup中计数器的值变为0。
我们可以通过以下示例来理解sync.WaitGroup的用法:
package main
import (
"fmt"
"sync"
)
func worker(id int, wg *sync.WaitGroup) {
defer wg.Done()
fmt.Printf("Worker %d starting\n", id)
// 模拟耗时操作
for i := 0; i < 1000000000; i++ {
_ = i
}
fmt.Printf("Worker %d done\n", id)
}
func main() {
var wg sync.WaitGroup
// 启动5个goroutine
for i := 1; i <= 5; i++ {
wg.Add(1)
go worker(i, &wg)
}
// 等待所有goroutine完成
wg.Wait()
fmt.Println("All workers done")
}
在这个示例中,我们定义了一个worker函数来模拟每个goroutine要执行的任务。在main函数中,我们启动了5个goroutine,并将它们添加到WaitGroup中。然后,我们调用Wait方法阻塞主线程,等待所有goroutine执行完毕。
需要注意的是,如果我们没有在worker函数中调用Done方法,则Wait方法会一直阻塞程序。因此,务必记得在每个goroutine中调用Done方法,以便让Wait方法知道何时结束阻塞。
总结来说,sync.WaitGroup提供了一种方便的方式来等待一组goroutine的执行。通过Add、Done和Wait方法的组合,我们可以轻松地实现这个功能。当然,在实际应用中,我们还需要注意一些细节,比如在goroutine中使用defer语句调用Done方法,以确保即使出现异常也能够正确地减少计数器的值。