Hi,大家好,我是明哥,
在自己學習 Golang 的這段時間里,我寫了詳細的學習筆記放在我的個人微信公眾號 《Go編程時光》,對于 Go 語言,我也算是個初學者,因此寫的東西應該會比較適合剛接觸的同學,如果你也是剛學習 Go 語言,不防關注一下,一起學習,一起成長,
我的在線博客:http://golang.iswbm.com
我的 Github:github.com/iswbm/GolangCodingTime
在前兩篇文章里,我們學習了 協程 和 信道 的內容,里面有很多例子,當時為了保證 main goroutine 在所有的 goroutine 都執行完畢后再退出,我使用了 time.Sleep 這種簡單的方式,
由于寫的 demo 都是比較簡單的, sleep 個 1 秒,我們主觀上認為是夠用的,
但在實際開發中,開發人員是無法預知,所有的 goroutine 需要多長的時間才能執行完畢,sleep 多了吧主程式就阻塞了, sleep 少了吧有的子協程的任務就沒法完成,
因此,使用time.Sleep 是一種極不推薦的方式,今天主要就要來介紹 一下如何優雅的處理這種情況,
1. 使用信道來標記完成
“不要通過共享記憶體來通信,要通過通信來共享記憶體”
學習了信道后,我們知道,信道可以實作多個協程間的通信,那么我們只要定義一個信道,在任務完成后,往信道中寫入true,然后在主協程中獲取到true,就認為子協程已經執行完畢,
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
2. 使用 WaitGroup
上面使用信道的方法,在單個協程或者協程數少的時候,并不會有什么問題,但在協程數多的時候,代碼就會顯得非常復雜,有興趣可以自己嘗試一下,
那么有沒有一種更加優雅的方式呢?
有,這就要說到 sync包 提供的 WaitGroup 型別,
WaitGroup 你只要實體化了就能使用
var 實體名 sync.WaitGroup
實體化完成后,就可以使用它的幾個方法:
- Add:初始值為0,你傳入的值會往計數器上加,這里直接傳入你子協程的數量
- Done:當某個子協程完成后,可呼叫此方法,會從計數器上減一,通常可以使用 defer 來呼叫,
- Wait:阻塞當前協程,直到實體里的計數器歸零,
舉一個例子:
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,,
系列導讀
01. 開發環境的搭建(Goland & VS Code)
02. 學習五種變數創建的方法
03. 詳解資料型別:****整形與浮點型
04. 詳解資料型別:byte、rune與string
05. 詳解資料型別:陣列與切片
06. 詳解資料型別:字典與布爾型別
07. 詳解資料型別:指標
08. 面向物件編程:結構體與繼承
09. 一篇文章理解 Go 里的函式
10. Go語言流程控制:if-else 條件陳述句
11. Go語言流程控制:switch-case 選擇陳述句
12. Go語言流程控制:for 回圈陳述句
13. Go語言流程控制:goto 無條件跳轉
14. Go語言流程控制:defer 延遲呼叫
15. 面向物件編程:介面與多型
16. 關鍵字:make 和 new 的區別?
17. 一篇文章理解 Go 里的陳述句塊與作用域
18. 學習 Go 協程:goroutine
19. 學習 Go 協程:詳解信道/通道
20. 幾個信道死鎖經典錯誤案例詳解
21. 學習 Go 協程:WaitGroup
22. 學習 Go 協程:互斥鎖和讀寫鎖
23. Go 里的例外處理:panic 和 recover
24. 超詳細解讀 Go Modules 前世今生及入門使用
25. Go 語言中關于包匯入必學的 8 個知識點
26. 如何開源自己寫的模塊給別人用?
27. 說說 Go 語言中的型別斷言?
28. 這五點帶你理解Go語言的select用法

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/6565.html
標籤:Go
