在其他的程式語言裡,當我們想要並發執行一段程式碼時,我們通常會在不同的線程之間共享資源,同時為了避免競爭條件的產生,我們又在共享資源上加鎖。
有句話是這麼說的
Do not communicate by sharing memory; instead, share memory by communicating.
不要依賴共享資源的方式通訊,而是依賴通訊的方式共享資源
上述是Go語言基於 CSP 模型實現的並發哲學。 CSP 也就是 通訊順序進程(Communicating sequential processes),我們可以將 goroutine 視為 CSP 模型中的實體,那麼 channel 便是不同的goroutine之間的通訊管道。 channel不但是線程安全的,還提供了"先進先出“的特性,並且能影響 goroutine 的阻塞和喚醒。
Channel類型的定義如下:
ChannelType = ( "chan" | "chan" "<-" | "<-" "chan" ) ElementType .
它的操作符為箭號 <-,箭號是可選參數,其方向代表channel的方向,若是不指向channel的方向,那麼Channel就是可以接收數據也可以發送數據的雙向通道。
chan <DataType> // 可以接收和發送指定的資料類型
chan<- float64 // 只可以用來發送 float64 類型
<-chan int // 只可以用來接收 int 類型
channel的基本操作有:創建、傳送、接收和關閉。
舉例:
ch := make(chan int) //創建一個Channel ch
ch <- u //將值u傳送到 Channel ch裡
v := <- ch //從Channel ch中接收數據 ,並且將其賦值給變數v
close(ch) //關閉channel
使用 make 初始化 Channel,並且可以設置Channel的容量:
make(chan int, 100)
容量代表Channel可以承載的最大元素數目,也就是 Channel 的緩存大小。如果 Channel 的緩存大小設置為0, Channel在通訊時會阻塞到 sender 和 receiver 兩者都準備好後才會開始通訊。在 Channel 有緩存的情況下, buffer 已滿時 send 會阻塞,緩存空了時 receive 會阻塞。未初始化的 nil Cahnnel不會有通訊能力。
可以通過內建的close方法關閉Channel
close(ch) //關閉channel
你可以在多个goroutine从/往 一个channel 中 receive/send 数据, 不必考虑额外的同步措施。
Channel可以作为一个先入先出(FIFO)的队列,接收的数据和发送的数据的顺序是一致的。
channel 的 receive 可以回傳ok參數,檢查 Channel是否已經被關閉了。
v, ok := <-ch
Channel 可以作為一個先進先出(FIFO)的隊列,接收數據和發送數據的順序是一致的。
一個 Channel 可以接收/發送多個 goroutine 的數據,不必考慮額外的同步問題。