您好,登錄后才能下訂單哦!
怎么在Golang中實現channel?很多新手對此不是很清楚,為了幫助大家解決這個難題,下面小編將為大家詳細講解,有這方面需求的人可以來學習下,希望你能有所收獲。
golang 是Google開發的一種靜態強類型、編譯型、并發型,并具有垃圾回收功能的編程語言,其語法與 C語言相近,但并不包括如枚舉、異常處理、繼承、泛型、斷言、虛函數等功能。
channel是Go語言在語言級別提供的goroutine間的通信方式,可以使用channel在兩個或多個goroutine之間傳遞消息。channel是進程內通信方式,因此通過channel傳遞對象的過程和調用函數時的參數傳遞行為比較一致,比如也可以傳遞指針。如果需要跨進程通信,建議使用分布式系統來解決,比如使用Socket或者HTTP等通信協議。
channel是類型相關的,也就是說,一個chennel只能傳遞一種類型的值,這個類型需要在聲明channel時指定。注意,在GO語言中channel本身也是一個原生類型,與map之類的類型地位一樣,因此channel本身在定義后也可以通過channel傳遞。
type hchan struct { qcount uint // 隊列中當前數據的個數 dataqsiz uint // size of the circular queue buf unsafe.Pointer // 數據緩沖區,存放數據的環形數組 elemsize uint16 // channel中數據類型的大小(單個元素的大小) closed uint32 // 表示channel是否關閉標識位 elemtype *_type // 隊列中的元素類型 sendx uint // 當前發送元素的索引 recvx uint // 當前接收元素的索引 recvq waitq // 接受等待隊列,由recv行為(也就是<-ch)阻塞在channel上的goroutine隊列 sendq waitq // 發送等待隊列, 由send行為(也就是ch<-)阻塞在channel上的goroutine隊列 //lock保護chann中的所有字段,以及在此通道上阻塞的sudoG中的幾個字段。 //保持此鎖時不要更改另一個G狀態(特別是沒準備好G),因為這可能會因堆棧收縮而死鎖 lock mutex } //發送及接收隊列的·1結構體 type waitq struct { first *sudog last *sudog }
qcount uint // 當前隊列中剩余元素個數。
dataqsiz uint // 環形隊列長度,即緩沖區的大小,即make(chan T,N),N。
buf unsafe.Pointer // 環形隊列指針。
elemsize uint16 // 每個元素的大小。
closed uint32 // 表示當前通道是否處于關閉狀態。創建通道后,該字段設置為0,即通道打開; 通過調用close將其設置為1,通道關閉。
elemtype *_type // 元素類型,用于數據傳遞過程中的賦值。
sendx uint 和 recvx uint是環形緩沖區的狀態字段,它指示緩沖區的當前索引 - 支持數組,它可以從中發送數據和接收數據。
recvq waitq // 等待讀消息的goroutine隊列。
sendq waitq // 等待寫消息的goroutine隊列。
lock mutex // 互斥鎖,為每個讀寫操作鎖定通道,因為發送和接收必須是互斥操作。
1.創建帶buffer的channel
2.向channel中寫入數據
3.3 寫入過程如下:
鎖定整個管道結構。
確定寫入,嘗試從等會帶隊列等待goroutine,然后將元素直接寫入goroutine。
如果recvq為空,則確定緩沖區是否可用。如果可用,從當前goroutine復制數據到緩沖區。
如果緩沖區已滿,則要寫入的元素將保存在當前正在執行的goroutine結構中,并且當前goroutine將在sendq中排隊并從運行中掛起。
寫入完成釋放鎖。
先讀取channel全局鎖。
嘗試sendq從等待隊列中獲取等待的goroutine。
如果有等待的goroutine,且有緩沖區(緩沖區已滿),從緩沖區隊首取出數據,再從sendq取出一個goroutine。將goroutine中數據存入buf對位,結束讀取釋放鎖。
如沒有后等待的goroutine,且緩沖區有數據,直接讀取緩沖區數據,解釋讀取釋放鎖。
如果沒有等待的goroutine,且沒有緩沖或緩沖區域為空,將當前的goroutine加入denq排隊,進入睡眠,等待被寫goroutine喚醒。結束釋放鎖。
看完上述內容是否對您有幫助呢?如果還想對相關知識有進一步的了解或閱讀更多相關文章,請關注億速云行業資訊頻道,感謝您對億速云的支持。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。