Go 通道(channel)的基本操作

2022-07-16 17:33:15 字數 2224 閱讀 5813

通道型別是go語言自帶的、唯一乙個可以滿足併發安全性的型別,在宣告並初始化乙個通道時,需要用到內建函式make,傳給make函式的第乙個引數應該代表通道的具體型別的型別字面量。

如型別字面量 chan int,其中chan表示通道型別的關鍵字,而int說明了該通道型別的元素型別。

在初始化通道時,make函式除了必須接受這樣的字面量作為引數,還可以接收乙個int型別的引數。後者是可選的,用於表示通道的容量(通道最多快取多少個元素值),不能小於0。當容量為0時稱其為非緩衝通道,當容量大於0時,可以稱為緩衝通道

乙個通道相當於乙個先進先出(fifo)的佇列。元素值的傳送和接收都需要用到操作符  <-

1

package main

23 import "

fmt"45

func main()

由於該通道容量為3,所以可以在通道不包含任何元素值的時候,連續地向該通道傳送三個值,此時這三個值都會被快取在通道之中。當從通道接收元素值的時候,同樣要用接送操作符 <-

1、對通道的傳送和接收操作都有哪些基本的特性?

1)對於同乙個通道,傳送操作之間是互斥的,接收操作之間也是互斥的

在同一時刻,go語言的執行時系統只會執行對同乙個通道的任意個傳送操作中的某乙個,知道這個元素值被完全複製進該通道之後,其他針對該通道的傳送操作才可能被執行

類似的,在同一時刻,執行時系統也只會執行對同乙個通道的任意個接收操作中的某乙個,直到這個元素值完全被移除該通道之後,其他針對該通道的接收操作才可能被執行。

另外,對於通道中的同乙個元素值來說,傳送操作和接收操作也是互斥的,雖會出現正在被複製進通道但還未複製完成的元素值,但此時它絕不會被想接收它的一方看到和取走

並且,元素值從外界進入通道時會被複製,進入通道的並不是接收操作符右邊那個元素值,而是它的副本。

2)傳送操作和接收操作中對元素值的處理都是不可分割的

不可分割的意思是處理元素值時是一氣呵成不會被打斷的

傳送操作要麼還沒複製元素值,要麼已經複製完畢,絕不會出現只複製一部分的情況

接收操作在準備好元素值的副本之後,一定會刪除通道中的原值,絕不會出現通道中仍有殘留的情況

對於通道中的桶乙個元素值來說,它只可能是某乙個傳送操作放入的,同時也只可能被某乙個接收操作取出

3)傳送操作在完成之前會被阻塞,接收操作也是

傳送操作包括「複製元素值」和「放置副本通道內部」兩個步驟,在這兩個步驟完全完成之前,發起這個傳送操作的那句**會一直阻塞在那裡,在它之後的**不會有執行的機會,直到這句**阻塞解除。在通道完成傳送操作之後,執行時系統會通知這句**所在                 的goroutine,以使它去爭取繼續執行**的機會

接收操作包括「複製通道內的元素」,「放置副本到接收方」,「刪掉原值」三個步驟,同理在這些步驟完全完成之前,發起該操作的**也會一直阻塞。

2、傳送操作和接收操作在什麼時候可能被長時間阻塞

1)緩衝通道

如果通道已滿,那麼對它的所有傳送操作都會被阻塞,直到通道中有元素值被接收走。通道會優先通知最早等待的那個傳送操作所在的goroutine,通知的順序總是公平的

如果通道已空,那麼對它的所以接收操作都會被阻塞,直到通道中有新的元素值出現,通道會優先通知最早等待的那個接收操作所在的goroutine,通知的順序總是公平的

2)非緩衝通道

無論傳送操作還是接收操作,一開始執行就會被阻塞,直到配對的操作也開始執行。即非緩衝通道是在用同步的方式傳遞資料,也就是說,只有收發雙方對接上了,資料才會被床底,資料是直接從傳送方複製到接收方的,中間並不會用非緩衝通道做中轉

3)對值為nil的通道

不論它的具體型別是什麼,對它的傳送操作和接收操作都會永久地處於阻塞狀態,它們所屬的goroutine中的任何**,都不會被執行。因此一定要初始化通道

3、傳送操作和接收操作在什麼時候會引發panic?

對於乙個已初始化,但並未關閉的通道來說,收發操作一定不會引發panic,但通道一旦關閉,再對它進行傳送操作,就會引發panic。

如果試圖關閉乙個已經關閉了的通道,也會引發panic

當把接收表示式結果同時賦值給兩個變數時,第二個變數的型別就是一定bool型別,它的值如果是false就說明通道已經關閉,並且再沒有元素值可取。如果通道關閉時,裡面還有元素值未被取出,那麼接收表示式的第乙個結果仍會是通道中的某乙個元素值,而第二個結果值一定會是true

go 通道 go語言通道channel

通過使用通道,在多個goroutine傳送和接受共享的資料,達到資料同步的目的。通道,他有點像在兩個routine之間架設的管道,乙個goroutine可以往這個管道裡塞資料,另外乙個可以從這個管道裡取資料,有點類似於我們說的佇列。宣告乙個通道很簡單,我們使用chan關鍵字即可,除此之外,還要指定通...

go語言基礎 快取通道 channel

非快取的通道,傳送和接收都是阻塞 帶快取的通道,有一塊快取區可以繼續傳送和接收資料。make chan t,size 快取區中已經滿了,才會阻塞程式 ch1 make chan int,5 ch1 100 不阻塞,因為有快取 ch1 200 ch1 300 ch1 400 ch1 500 快取區已滿...

go基礎知識 通道 channel

1.channel go特殊的資料型別,用於通訊,使用的時候需要注意下結合使用不當容易造成死鎖,在結合 for select 裡使用break是沒效果的 2.語法定義 chan 讀取,chan 寫入 var cha make chan type,len 有緩衝 var chb make chan t...