golang 併發控制(1)Channel
阿新 • • 發佈:2021-08-20
1. 前言
channel一般用於協程之間的通訊,channel也可以用於併發控制。比如主協程啟動N個子協程,主協程等待所有子協程退出後再繼續後續流程,這種場景下channel也可輕易實現。
2. 場景示例
下面程式展示一個使用channel控制子協程的例子:
package main import ( "time" "fmt" ) func Process(ch chan int) { //Do some work... time.Sleep(time.Second) ch <- 1 //管道中寫入一個元素表示當前協程已結束 } func main() { channels := make([]chan int, 10) //建立一個10個元素的切片,元素型別為channel for i:= 0; i < 10; i++ { channels[i] = make(chan int) //切片中放入一個channel go Process(channels[i]) //啟動協程,傳一個管道用於通訊 } for i, ch := range channels { //遍歷切片,等待子協程結束 <-ch fmt.Println("Routine ", i, " quit!") } }
上面程式通過建立N個channel來管理N個協程,每個協程都有一個channel用於跟父協程通訊,父協程建立完所有協程後等待所有協程結束。
這個例子中,父協程僅僅是等待子協程結束,其實父協程也可以向管道中寫入資料通知子協程結束,這時子協程需要定期地探測管道中是否有訊息出現。
3. 總結
使用channel來控制子協程的優點是實現簡單,缺點是當需要大量建立協程時就需要有相同數量的channel,而且對於子協程繼續派生出來的協程不方便控制。
後面繼續介紹的WaitGroup、Context看起來比channel優雅一些,在各種開源元件中使用頻率比channel高得多。