作用
當(dāng)主線程啟動(dòng)一組線程之后妖啥,WaitGroup會等待這組goroutines完成
sync.WaitGroup的方法
sync.WaitGroup的同步主要是根據(jù)內(nèi)部的一個(gè)計(jì)數(shù)器來操作的,通過內(nèi)部計(jì)數(shù)器的值來判斷當(dāng)前需要等待的goroutines的個(gè)數(shù).
sync.WaitGroup有如下三個(gè)方法:
Add():增加當(dāng)前要等待的goroutine的個(gè)數(shù),如果是負(fù)數(shù)沿腰,就是減少等待的goroutine的個(gè)數(shù)杰妓。當(dāng)小于零時(shí)蓬痒,代碼會出現(xiàn)panic
Gone():表示當(dāng)前goroutine執(zhí)行完成诈乒,減少Wait的goroutine的個(gè)數(shù)围肥,內(nèi)部執(zhí)行的是:Add(-1)
Wait():阻塞當(dāng)前主線程剿干,等待goroutine的執(zhí)行,當(dāng)wait.Group內(nèi)部的counter為零時(shí)穆刻,繼續(xù)向下執(zhí)行當(dāng)前的主線程
注:sync.WaitGroup對象不是一個(gè)引用類型置尔,通過函數(shù)傳遞的時(shí)候要使用地址,否則傳遞過去的只是一個(gè)當(dāng)前的copy氢伟,不會對當(dāng)前的對象產(chǎn)生影響
sync.WaitGroup Exmaple
var total struct {
sync.Mutex
value int
}
func worker(wg *sync.WaitGroup) {
defer wg.Done() //wg的counter減一
for i := 0; i < 100; i++ {
total.Lock()
total.value++
total.Unlock()
}
}
func main() {
var wg sync.WaitGroup
wg.Add(2) //此處添加要等待的goroutine的個(gè)數(shù)為2
go worker(&wg)
go worker(&wg)
wg.Wait() //阻塞當(dāng)前主線程直到wg等待的goroutine的個(gè)數(shù)為零
fmt.Println(total.value)
}
注:
var total struct {
sync.Mutex
value int
}
type total struct{
sync.Mutex
value int
}
這兩者的區(qū)別:
前者是變量榜轿,使用之前不用聲明,不能為該變量定義方法朵锣,但可以調(diào)用該變量中成員的方法谬盐,如:
total.Lock() //合法
func (t total) add(){} //非法
后者是類型,可以為該類型定義方法诚些,也可以調(diào)用該類型成員的方法飞傀,但在使用之前需要聲明,如:
t = new(total)
t.Lock
func (t total) Add(){}