日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

go WaitGroup的使用

發(fā)布時間:2024/2/28 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 go WaitGroup的使用 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

WaitGroup用于等待一組線程的結(jié)束。父線程調(diào)用Add方法來設(shè)定應(yīng)等待的線程的數(shù)量。每個被等待的線程在結(jié)束時應(yīng)調(diào)用Done方法。同時,主線程里可以調(diào)用Wait方法阻塞至所有線程結(jié)束。?
但在使用時,也有一些問題需要注意,請看本文的詳細(xì)分解。?
另外,WaitGroup的使用場景十分有限,為什么呢?具體原因,請看本文的總結(jié)部分的分析。

主要函數(shù)

func (*WaitGroup) Add

func (wg *WaitGroup) Add(delta int)

Add方法向內(nèi)部計數(shù)加上delta,delta可以是負(fù)數(shù);如果內(nèi)部計數(shù)器變?yōu)?,Wait方法阻塞等待的所有協(xié)程都會釋放,如果計數(shù)器小于0,則調(diào)用panic。注意Add加上正數(shù)的調(diào)用應(yīng)在Wait之前,否則Wait可能只會等待很少的協(xié)程。一般來說本方法應(yīng)在創(chuàng)建新的協(xié)程或者其他應(yīng)等待的事件之前調(diào)用。

func (wg *WaitGroup) Done()

func (wg *WaitGroup) Done()

Done方法減少WaitGroup計數(shù)器的值,應(yīng)在協(xié)程的最后執(zhí)行。

func (wg *WaitGroup) Wait()

func (wg *WaitGroup) Wait()?

Wait方法阻塞直到WaitGroup計數(shù)器減為0。

編程實戰(zhàn)

等待某個協(xié)程結(jié)束

func main() {var wg sync.WaitGroupwg.Add(1)go func() {defer wg.Done()fmt.Println("1 goroutine sleep ...")time.Sleep(2e9)fmt.Println("1 goroutine exit ...")}()wg.Add(1)go func() {defer wg.Done()fmt.Println("2 goroutine sleep ...")time.Sleep(4e9)fmt.Println("2 goroutine exit ...")}()fmt.Println("waiting for all goroutine ")wg.Wait()fmt.Println("All goroutines finished!") }

小結(jié)

要注意Add和Done函數(shù)一定要配對,否則可能發(fā)生死鎖,所報的錯誤信息如下:

fatal error: all goroutines are asleep - deadlock!
等待協(xié)程組結(jié)束

func main() {sayHello := func(wg *sync.WaitGroup, id int) {defer wg.Done()fmt.Printf("%v goroutine start ...\n", id)time.Sleep(2)fmt.Printf("%v goroutine exit ...\n", id)}var wg sync.WaitGroupconst N = 5wg.Add(N)for i := 0; i < N; i++ {go sayHello(&wg, i)}fmt.Println("waiting for all goroutine ")wg.Wait()fmt.Println("All goroutines finished!") }

運行以上程序,輸出如下:

waiting for all goroutine? 1 goroutine start ... 5 goroutine start ... 5 goroutine exit ... 4 goroutine start ... 4 goroutine exit ... 3 goroutine start ... 1 goroutine exit ... 0 goroutine start ... 3 goroutine exit ... 0 goroutine exit ... 2 goroutine start ... 2 goroutine exit ... All goroutines finished!

無論運行多少次,都能保證All goroutines finished!這一句在最后一行輸出,這說明,Wait()函數(shù)等了所有協(xié)程都結(jié)束自己才返回。

小結(jié)

以上程序通過WaitGroup提供的三個同步接口,實現(xiàn)了等待一個協(xié)程組完成的同步操作。在實現(xiàn)時要注意:?
* Add的參數(shù)N必須和創(chuàng)建的goroutine的數(shù)量相等,否則會報出死鎖的錯誤信息?
* 另外,sayHello()函數(shù)中要傳遞WaitGroup的指針呢?在該結(jié)構(gòu)的實現(xiàn)源碼中已經(jīng)有講解:

A WaitGroup must not be copied after first use.
就是說,該結(jié)構(gòu)定義后就不能被復(fù)制,所以這里要使用指針。
總結(jié)

通過WaitGroup提供的三個函數(shù):Add,Done,Wait,可以輕松實現(xiàn)等待某個協(xié)程或協(xié)程組完成的同步操作。但在使用時要注意:

Add的數(shù)量和Done的調(diào)用數(shù)量必須相等。
另外,就是WaitGroup結(jié)構(gòu)一旦定義就不能復(fù)制的原因。
WaitGroup在需要等待多個任務(wù)結(jié)束再返回的業(yè)務(wù)來說還是很有用的,但現(xiàn)實中用的更多的可能是,先等待一個協(xié)程組,若所有協(xié)程組都正確完成,則一直等到所有協(xié)程組結(jié)束;若其中有一個協(xié)程發(fā)生錯誤,則告訴協(xié)程組的其他協(xié)程,全部停止運行(本次任務(wù)失敗)以免浪費系統(tǒng)資源。?
該場景WaitGroup是無法實現(xiàn)的,那么該場景該如何實現(xiàn)呢,就需要用到通知機制,其實也可以用channel來實現(xiàn),具體的解決辦法,請看后續(xù)的文章。?
這樣說來,WaitGroup的使用場景是有限的。

總結(jié)

以上是生活随笔為你收集整理的go WaitGroup的使用的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。