Hi,你們好,我是明哥。git
在本身學習 Golang 的這段時間裏,我寫了詳細的學習筆記放在個人我的微信公衆號 《Go編程時光》,對於 Go 語言,我也算是個初學者,所以寫的東西應該會比較適合剛接觸的同窗,若是你也是剛學習 Go 語言,不防關注一下,一塊兒學習,一塊兒成長。github
個人在線博客:golang.iswbm.com 個人 Github:github.com/iswbm/GolangCodingTimegolang
在前兩篇文章裏,咱們學習了 協程
和 信道
的內容,裏面有不少例子,當時爲了保證 main goroutine 在全部的 goroutine 都執行完畢後再退出,我使用了 time.Sleep 這種簡單的方式。編程
因爲寫的 demo 都是比較簡單的, sleep 個 1 秒,咱們主觀上認爲是夠用的。微信
但在實際開發中,開發人員是沒法預知,全部的 goroutine 須要多長的時間才能執行完畢,sleep 多了吧主程序就阻塞了, sleep 少了吧有的子協程的任務就無法完成。學習
所以,使用time.Sleep 是一種極不推薦的方式,今天主要就要來介紹 一下如何優雅的處理這種狀況。spa
「不要經過共享內存來通訊,要經過通訊來共享內存」code
學習了信道後,咱們知道,信道能夠實現多個協程間的通訊,那麼咱們只要定義一個信道,在任務完成後,往信道中寫入true,而後在主協程中獲取到true,就認爲子協程已經執行完畢。cdn
import "fmt"
func main() {
done := make(chan bool)
go func() {
for i := 0; i < 5; i++ {
fmt.Println(i)
}
done <- true
}()
<-done
}複製代碼
輸出以下協程
0
1
2
3
4複製代碼
上面使用信道的方法,在單個協程或者協程數少的時候,並不會有什麼問題,但在協程數多的時候,代碼就會顯得很是複雜,有興趣能夠本身嘗試一下。
那麼有沒有一種更加優雅的方式呢?
有,這就要說到 sync包 提供的 WaitGroup 類型。
WaitGroup 你只要實例化了就能使用
var 實例名 sync.WaitGroup 複製代碼
實例化完成後,就可使用它的幾個方法:
舉一個例子:
import (
"fmt"
"sync"
)
func worker(x int, wg *sync.WaitGroup) {
defer wg.Done()
for i := 0; i < 5; i++ {
fmt.Printf("worker %d: %d\n", x, i)
}
}
func main() {
var wg sync.WaitGroup
wg.Add(2)
go worker(1, &wg)
go worker(2, &wg)
wg.Wait()
}複製代碼
輸出以下
worker 2: 0
worker 2: 1
worker 2: 2
worker 2: 3
worker 2: 4
worker 1: 0
worker 1: 1
worker 1: 2
worker 1: 3
worker 1: 4複製代碼
以上就是咱們在 Go 語言中實現一主多子的協程協做方式,推薦使用 sync.WaitGroup。。