Go並發控制Channel使用場景分析
1. 前言
channel一個類型管道,通過它可以在goroutine之間發送和接收消息。它是Golang在語言層面提供的goroutine間的通信方式。
Channel是Go中的一個核心類型,你可以把它看成一個管道,通過它並發核心單元就可以發送或者接收數據進行通訊(communication)。
它的操作符是箭頭 <- 。
我們考慮這麼一種場景,協程A執行過程中需要創建子協程A1、A2、A3…An,協程A創建完子協程後就等待子協程退出。
針對這種場景,GO提供瞭三種解決方案:
- Channel: 使用channel控制子協程
- WaitGroup : 使用信號量機制控制子協程
- Context: 使用上下文控制子協程
三種方案各有優劣,比如Channel優點是實現簡單,清晰易懂,WaitGroup優點是子協程個數動態可調整,Context優點是對子協程派生出來的孫子協程的控制。
缺點是相對而言的,要結合實例應用場景進行選擇。
channel一般用於協程之間的通信,channel也可以用於並發控制。比如主協程啟動N個子協程,主協程等待所有子協程退出後再繼續後續流程,這種場景下channel也可輕易實現。
2. 使用channel控制子協程
2.1 使用場景
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用於跟父協程通信,父協程創建完所有協程後等待所有協程結束。
這個例子中,父協程僅僅是等待子協程結束,其實父協程也可以向管道中寫入數據通知子協程結束,這時子協程需要定期地探測管道中是否有消息出現。
2.2 總結
使用channel來控制子協程的優點是實現簡單,缺點是當需要大量創建協程時就需要有相同數量的channel,而且對於子協程繼續派生出來的協程不方便控制。
到此這篇關於Go並發控制Channel使用場景分析的文章就介紹到這瞭,更多相關Go並發控制Channel內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- Go語言如何輕松編寫高效可靠的並發程序
- 示例剖析golang中的CSP並發模型
- golang coroutine 的等待與死鎖用法
- Go緩沖channel和非緩沖channel的區別說明
- 詳解Go語言中Goroutine退出機制的原理及使用