1. 前言
channel一個類型管道,通過它可以在goroutine之間發(fā)送和接收消息。它是Golang在語言層面提供的goroutine間的通信方式。
Channel是Go中的一個核心類型,你可以把它看成一個管道,通過它并發(fā)核心單元就可以發(fā)送或者接收數(shù)據(jù)進行通訊(communication)。
它的操作符是箭頭 - 。
我們考慮這么一種場景,協(xié)程A執(zhí)行過程中需要創(chuàng)建子協(xié)程A1、A2、A3…An,協(xié)程A創(chuàng)建完子協(xié)程后就等待子協(xié)程退出。
針對這種場景,GO提供了三種解決方案:
- Channel: 使用channel控制子協(xié)程
- WaitGroup : 使用信號量機制控制子協(xié)程
- Context: 使用上下文控制子協(xié)程
三種方案各有優(yōu)劣,比如Channel優(yōu)點是實現(xiàn)簡單,清晰易懂,WaitGroup優(yōu)點是子協(xié)程個數(shù)動態(tài)可調(diào)整,Context優(yōu)點是對子協(xié)程派生出來的孫子協(xié)程的控制。
缺點是相對而言的,要結(jié)合實例應(yīng)用場景進行選擇。
channel一般用于協(xié)程之間的通信,channel也可以用于并發(fā)控制。比如主協(xié)程啟動N個子協(xié)程,主協(xié)程等待所有子協(xié)程退出后再繼續(xù)后續(xù)流程,這種場景下channel也可輕易實現(xiàn)。
2. 使用channel控制子協(xié)程
2.1 使用場景
package main
import (
"time"
"fmt"
)
func Process(ch chan int) {
//Do some work...
time.Sleep(time.Second)
ch - 1 //管道中寫入一個元素表示當(dāng)前協(xié)程已結(jié)束
}
func main() {
channels := make([]chan int, 10) //創(chuàng)建一個10個元素的切片,元素類型為channel
for i:= 0; i 10; i++ {
channels[i] = make(chan int) //切片中放入一個channel
go Process(channels[i]) //啟動協(xié)程,傳一個管道用于通信
}
for i, ch := range channels { //遍歷切片,等待子協(xié)程結(jié)束
-ch
fmt.Println("Routine ", i, " quit!")
}
}
上面程序通過創(chuàng)建N個channel來管理N個協(xié)程,每個協(xié)程都有一個channel用于跟父協(xié)程通信,父協(xié)程創(chuàng)建完所有協(xié)程后等待所有協(xié)程結(jié)束。
這個例子中,父協(xié)程僅僅是等待子協(xié)程結(jié)束,其實父協(xié)程也可以向管道中寫入數(shù)據(jù)通知子協(xié)程結(jié)束,這時子協(xié)程需要定期地探測管道中是否有消息出現(xiàn)。
2.2 總結(jié)
使用channel來控制子協(xié)程的優(yōu)點是實現(xiàn)簡單,缺點是當(dāng)需要大量創(chuàng)建協(xié)程時就需要有相同數(shù)量的channel,而且對于子協(xié)程繼續(xù)派生出來的協(xié)程不方便控制。
到此這篇關(guān)于Go并發(fā)控制Channel使用場景分析的文章就介紹到這了,更多相關(guān)Go并發(fā)控制Channel內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
您可能感興趣的文章:- Go并發(fā)控制WaitGroup的使用場景分析
- Golang 實現(xiàn)分片讀取http超大文件流和并發(fā)控制
- Go 并發(fā)控制context實現(xiàn)原理剖析(小結(jié))
- Django Channels 實現(xiàn)點對點實時聊天和消息推送功能
- 基于django channel實現(xiàn)websocket的聊天室的方法示例