在Go語(yǔ)言中,WaitGroup是一個(gè)用于等待一組goroutine完成執(zhí)行的工具。它可以用來(lái)協(xié)調(diào)多個(gè)并發(fā)任務(wù)的執(zhí)行和等待,確保所有任務(wù)完成后再繼續(xù)執(zhí)行主線程。
下面是一個(gè)使用WaitGroup的簡(jiǎn)單示例:
package main
import (
"fmt"
"sync"
"time"
)
func worker(id int, wg *sync.WaitGroup) {
defer wg.Done()
fmt.Printf("Worker %d starting\n", id)
time.Sleep(time.Second)
fmt.Printf("Worker %d done\n", id)
}
func main() {
var wg sync.WaitGroup
for i := 1; i <= 5; i++ {
wg.Add(1)
go worker(i, &wg)
}
wg.Wait()
fmt.Println("All workers done")
}
在這個(gè)例子中,我們定義了一個(gè)worker
函數(shù),它接受一個(gè)id和一個(gè)WaitGroup
參數(shù)。在函數(shù)開始時(shí),它調(diào)用wg.Done()
來(lái)通知WaitGroup
任務(wù)完成。在主函數(shù)中,我們循環(huán)創(chuàng)建5個(gè)worker goroutine,并且在每個(gè)goroutine啟動(dòng)之前調(diào)用wg.Add(1)
來(lái)增加WaitGroup的計(jì)數(shù)。最后,我們調(diào)用wg.Wait()
來(lái)等待所有g(shù)oroutine完成執(zhí)行。
輸出結(jié)果可能是這樣的:
Worker 1 starting
Worker 5 starting
Worker 2 starting
Worker 3 starting
Worker 4 starting
Worker 4 done
Worker 1 done
Worker 2 done
Worker 3 done
Worker 5 done
All workers done
需要注意的是,WaitGroup的計(jì)數(shù)不能為負(fù)數(shù),因此在調(diào)用wg.Done()
之前,我們必須確保每個(gè)goroutine都調(diào)用了wg.Add(1)
。
WaitGroup還有一個(gè)常用的方法wg.Add(delta int)
,可以一次性增加或減少計(jì)數(shù)器的值。這在任務(wù)分發(fā)與負(fù)載均衡中也很有用。
例如,如果你有一個(gè)任務(wù)列表,想要將任務(wù)分配給一組goroutine進(jìn)行并發(fā)處理,你可以使用WaitGroup來(lái)等待所有任務(wù)完成。在分配任務(wù)時(shí),可以使用wg.Add(len(tasks))
來(lái)一次性增加WaitGroup的計(jì)數(shù)器,然后每個(gè)goroutine完成任務(wù)時(shí)調(diào)用wg.Done()
來(lái)減少計(jì)數(shù)器。
總結(jié)來(lái)說(shuō),Go語(yǔ)言的WaitGroup是一個(gè)非常有用的工具,可以幫助我們協(xié)調(diào)多個(gè)并發(fā)任務(wù)的執(zhí)行和等待。通過(guò)合理地使用WaitGroup,我們可以實(shí)現(xiàn)任務(wù)分發(fā)和負(fù)載均衡,以提高并發(fā)程序的性能和效率。