亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

怎么在Golang中實現channel

發布時間:2021-05-06 17:48:03 來源:億速云 閱讀:249 作者:Leah 欄目:編程語言

怎么在Golang中實現channel?很多新手對此不是很清楚,為了幫助大家解決這個難題,下面小編將為大家詳細講解,有這方面需求的人可以來學習下,希望你能有所收獲。

什么是golang

golang 是Google開發的一種靜態強類型、編譯型、并發型,并具有垃圾回收功能的編程語言,其語法與 C語言相近,但并不包括如枚舉、異常處理、繼承、泛型、斷言、虛函數等功能。

一.簡介

channel是Go語言在語言級別提供的goroutine間的通信方式,可以使用channel在兩個或多個goroutine之間傳遞消息。channel是進程內通信方式,因此通過channel傳遞對象的過程和調用函數時的參數傳遞行為比較一致,比如也可以傳遞指針。如果需要跨進程通信,建議使用分布式系統來解決,比如使用Socket或者HTTP等通信協議。

channel是類型相關的,也就是說,一個chennel只能傳遞一種類型的值,這個類型需要在聲明channel時指定。注意,在GO語言中channel本身也是一個原生類型,與map之類的類型地位一樣,因此channel本身在定義后也可以通過channel傳遞。

二.底層實現

2.1 hchan結構

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 // 互斥鎖,為每個讀寫操作鎖定通道,因為發送和接收必須是互斥操作。

2.2 創建過程

2.2.1 寫入操作

1.創建帶buffer的channel

怎么在Golang中實現channel

2.向channel中寫入數據

怎么在Golang中實現channel

怎么在Golang中實現channel

3.3 寫入過程如下:

怎么在Golang中實現channel

  • 鎖定整個管道結構。

  • 確定寫入,嘗試從等會帶隊列等待goroutine,然后將元素直接寫入goroutine。

  • 如果recvq為空,則確定緩沖區是否可用。如果可用,從當前goroutine復制數據到緩沖區。

  • 如果緩沖區已滿,則要寫入的元素將保存在當前正在執行的goroutine結構中,并且當前goroutine將在sendq中排隊并從運行中掛起。

  • 寫入完成釋放鎖。

2.2.2 讀取過程

怎么在Golang中實現channel

怎么在Golang中實現channel

怎么在Golang中實現channel

  • 先讀取channel全局鎖。

  • 嘗試sendq從等待隊列中獲取等待的goroutine。

  • 如果有等待的goroutine,且有緩沖區(緩沖區已滿),從緩沖區隊首取出數據,再從sendq取出一個goroutine。將goroutine中數據存入buf對位,結束讀取釋放鎖。

  • 如沒有后等待的goroutine,且緩沖區有數據,直接讀取緩沖區數據,解釋讀取釋放鎖。

  • 如果沒有等待的goroutine,且沒有緩沖或緩沖區域為空,將當前的goroutine加入denq排隊,進入睡眠,等待被寫goroutine喚醒。結束釋放鎖。

看完上述內容是否對您有幫助呢?如果還想對相關知識有進一步的了解或閱讀更多相關文章,請關注億速云行業資訊頻道,感謝您對億速云的支持。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

博白县| 古田县| 安吉县| 凭祥市| 方城县| 平潭县| 吴江市| 包头市| 栾城县| 乌兰察布市| 巴林左旗| 依安县| 大宁县| 化州市| 北票市| 九龙县| 丰原市| 祁连县| 曲周县| 乡城县| 寻乌县| 疏附县| 泰来县| 定远县| 沭阳县| 河北区| 股票| 阿拉善盟| 龙岩市| 武强县| 岐山县| 绥阳县| 许昌市| 屯留县| 咸阳市| 宁城县| 习水县| 西城区| 水城县| 南靖县| 沾益县|