久久国产精品一区二区三区四区,久色婷婷小香蕉久久,国产日韩欧美在线播放不卡,另类av一区二区

每日焦點!深入解析Go Channel各狀態下的操作結果
來源:Go學堂    時間:2023-06-15 08:05:36

大家好,我是漁夫子。


(資料圖片)

channel是golang中獨有的特性,也是面試中經常被問到的。相信大家都看到過下面這張圖,對于不同狀態下通道,在操作時會有什么結果。

這張圖總結的非常好。但我們不能死記硬背這些結果。要了解其底層的基本原理,就能理解這些結果是怎么來的。

我們分三部分來講。先是channel的基礎使用,基礎使用提現了channel有哪些特性。再引出channel的底層數據結構。底層數據結構就是圍繞這些特性而建立的。最后再看go是如何基于底層數據結構來實現這些特性的。

channel的基礎使用通道的定義和初始化通過var定義通道

通過var定義一個通道變量ch,這個變量能夠接收整型的數據。當然也可以指定其他任何數據類型。

var ch chan intch 代表變量名chan固定值。代表ch是通道類型int代表在通道ch中存儲的是整型數據。ch變量的默認值是nil。對于nil通道在操作時會有特殊的場景,一會我們也會講解。通過make初始化通道

通過make可以初始化無緩沖區通道和緩沖區通道。區別就在于make中是否指定了緩沖區的大小。如下:

var ch = make(chan int) //初始化無緩沖通道var ch = make(chan int, 10) //緩沖區通道,緩沖區可以存10個元素

無緩沖通道和有緩沖通道的區別可以從屬性上和行為兩方面來體現:

從屬性上區別:通道是否有一段緩沖區來暫存元素。從行為上區別:發送者和接收者是否同步的還是異步的。從底層數據結構上區別:是否有一塊緩沖區來暫存數據。這個后面會詳細講解。通道的操作

golang中對于通道有三種操作:往通道中發送元素、從通道中接收元素、關閉通道。如下:往通道中發送元素:

var ch chan int = make(chan int, 10)2 ->ch //發送元素var item intitem <-ch //接收元素close(ch) //關閉元素

總結一下:

通道有三種操作:發送、接收和關閉。通道有三種類型:nil通道、無緩沖通道和有緩沖通道。通道有2種狀態:關閉狀態和未關閉狀態。緩沖通道的未關閉狀態又可以分為緩沖區滿、緩沖區未滿狀態。

那么,通道是基于怎樣的數據結構來完成這些行為的呢?

channel的數據結構

我們先給出channel的底層數據結構,如下:

type hchan struct { qcount uint // total data in the queue dataqsiz uint // size of the circular queue buf unsafe.Pointer // points to an array of dataqsiz elements elemsize uint16 closed uint32 elemtype *_type // element type sendx uint // send index recvx uint // receive index recvq waitq // list of recv waiters sendq waitq // list of send waiters // lock protects all fields in hchan, as well as several // fields in sudogs blocked on this channel. // // Do not change another G"s status while holding this lock // (in particular, do not ready a G), as this can deadlock // with stack shrinking. lock mutex}type waitq struct { first *sudog last *sudog}

根據上面的結構定義,依次解釋下各個字段的含義:

buf:指向一個數組,代表的是一個隊列,結合sendx和recvx字段實現了環形隊列。緩存對應的元素。緩沖區通道就是利用這個字段實現的。qcount:在buf隊列中當前有多少個元素。dataqsiz:代表隊列buf的容量。在使用make進行初始化時,指定的元素個數就存在該字段中。elemsize:一個元素的字節大小。根據該元素的大小,可以初始化buf的容量的大小。通過elemsize*容量就能知道該給buf分配多少字節的空間了。closed:代表該通道是否被關閉。其值只有0和1。1代表該通道已經關閉了。0代表未關閉。elemtype:代表元素的類型。sendx:代表的是發送下一個元素應該存儲的位置recvx:代表的是下一個接收元素的位置。recvq:代表的是等待接收元素的協程隊列sendq:代表的是發送元素的協程隊列。

根據以上結果,繪制成圖會容易理解點,如下:

緩沖通道和非緩沖通道的區別

從定義上,緩沖通道和非緩沖通道都是通過make來初始化的。不同點在于是否在make函數上指定了通道的容量大小。如下:

unbufferCh := make(chan int) //初始化非緩沖區通道bufferCh := make(chan int, 10) //初始化一個能緩沖10個元素的通道

從通道的底層數據結構上來說,非緩沖渠道不會初始化結構體中的buf字段。而緩沖渠道則會初始化buf字段。該字段指向一塊內存區域。如下圖:

通道的發送、接收流程

通過源碼我們梳理出來了給通道發送數據和從通道中接收數據的流程圖。這張流程圖將緩沖通道和無緩沖通道兩種狀態下的發送和接收流程都包含了,所以看起來會比較復雜。但是沒關系,下面我們會分解這張圖。

通過上面的流程,大家需要注意的一點就是,無論是在發送還是接收操作時,都是優先從等待隊列中獲取對應的線程,如果有,則直接接收或發送;如果等待隊列沒有協程,然后再看是否有緩沖區。這一點需要大家額外注意。

各狀態通道的操作無緩沖通道

根據上述無緩沖通道其實本質上就是沒有緩沖區。在初始化時不指定make的容量即可。實際上這也叫做同步發送和接收。針對這種狀態的通道,當發送數據時,如果接收隊列中有等待的接收協程,那么就能發送成功;否則,進入阻塞狀態。反之,亦然。其流程圖就是圖中的紅色箭頭部分,如下:

再簡化一下就是:

往無緩沖區中發送數據時,如果有等待接收的協程,則發送成功;否則,發送協程進入阻塞狀態。從無緩沖區接收數據時,如果有等待發送的協程,則接收成功;否則,接收協程進入阻塞狀態。

那么,上面的圖可以簡化成如下:

另外需要額外注意一點,對于非緩沖區通道的發送和接收操作。如果是在main函數中進行發送和接收,那么會造成死鎖。如下:

func main() { var ch = make(chan int) <-ch fmt.Println("the End")}//或func main() { var ch = make(chan int) ch <- 2 fmt.Println("the End")}

所以,對于非緩沖區通道的發送和接收操作,最主要的問題就是可能會造成阻塞。除非,兩個發送和接收協程都存在,而且要在不同的協程里。

有緩沖通道

有緩沖區通道就是在通道中有一塊緩沖區,發送和接收都可以針對緩沖區進行操作。也稱為異步發送和接收。在有緩沖通道的狀態下,j對于發送操作來說,有緩沖通道的狀態分為緩沖區滿和未滿兩種狀態。根據上面的發送流程圖來說,當緩沖區滿了,自然就不能再發送了,就會進入等待發送隊列。同時阻塞,等待被接收協程喚醒。

對于接收操作來說,有緩沖通道的狀態分為緩沖區空和未滿兩種狀態。同樣,如果當緩沖區空時,無數據可接收,自然就進入到接收等待隊列。同時進入阻塞,等待被發送協程喚醒。

已關閉狀態的通道

關閉通道是通過**close**函數進行的。本質上關閉一個通道,就是將通道結構中的closed字段置為 1。從源代碼中可以獲知:

關閉nil通道:panic關閉已經關閉了的通道:panic。這一點可以這樣理解,關閉一個已經關閉的通道是沒有任何意義的。發送消息到已關閉的通道

給已經關閉了的通道發送消息會引發panic。這個很好理解,因為通道已經關閉,就是為了不讓發消息了。如下代碼:

從已關閉的通道接收消息

從已關閉的通道中接收消息時,都能操作成功。但會根據通道中是否有元素有以下不同:

如果通道中已經沒有元素了,則會返回一個false的狀態。如果通道中有元素,則會繼續接收通道中的元素,直到接收完,并返回false。

你看,其實代碼也很簡單。我們將代碼拆解一下,就是右側的流程圖。

nil通道

通過以下方式定義的通道類型的變量,其默認值就是nil。

var ch chan int

nil通道相當于沒有分配通道的底層結構

如下是從源代碼中截取的各個操作以及對應操作結果。通過源代碼可獲知:

關閉nil通道會panic從nil通道接收、發送消都會阻塞總結

golang中的通道就是用來在協程間進行通信的。我們從源碼級別推導了針對通道的各個狀態下的操作所產生的結果。最后總結一下:緩沖區通道:

只要有緩沖空間就能發送成功。除非緩沖空間滿了,則產生阻塞。只要緩沖空間中有元素就能接收成功。除非沒有元素,則產生阻塞。

nil通道:

nil通道是沒有初始化底層數據結構的通道。因為沒有空間可存儲任何元素,所以發送和接收都會產生阻塞。關閉nil通道,則會引發panic。

已關閉的通道:

往已關閉的通道中發送消息,會引發panic。從已關閉通道中接收消息,會成功。關閉已關閉的通道,也會引發panic。

關鍵詞:

X 關閉

X 關閉

久久国产精品一区二区三区四区,久色婷婷小香蕉久久,国产日韩欧美在线播放不卡,另类av一区二区
国产精品婷婷| 亚洲第一精品久久忘忧草社区| 一区二区三区黄色| 欧美色道久久88综合亚洲精品| 国产欧美日韩一区二区三区在线| 亚洲在线观看免费视频| 欧美大尺度在线观看| 国产欧美成人| 国产精品va| 亚洲高清视频中文字幕| 亚洲欧美一区二区视频| 亚洲第一主播视频| 亚洲国产成人一区| 欧美日韩不卡一区| 午夜在线电影亚洲一区| 亚洲国产精品久久久久秋霞影院| 久久成人免费日本黄色| 在线中文字幕不卡| 国产欧美日韩高清| 欧美日韩国产天堂| 国产欧美视频一区二区三区| 久久综合网hezyo| 久久国产精品黑丝| 中文日韩在线| 国产精品一区免费在线观看| 国产亚洲精品成人av久久ww| 国产日韩精品一区二区| 国产酒店精品激情| 亚洲一区二区三区色| 亚洲精品久久久久久久久久久久| 国产精品入口日韩视频大尺度| 永久域名在线精品| 欧美视频日韩视频| 欧美 日韩 国产一区二区在线视频| 宅男精品导航| 欧美欧美在线| 免费日韩精品中文字幕视频在线| 一本色道精品久久一区二区三区| 国产亚洲精品7777| 国产精品福利影院| 99精品国产在热久久下载| 欧美午夜久久久| 久久综合狠狠综合久久激情| 国产农村妇女精品一二区| 国产一区二区三区无遮挡| 国产精品影音先锋| 欧美一区二区三区久久精品茉莉花| 两个人的视频www国产精品| 一区二区三区回区在观看免费视频| 欧美巨乳波霸| 久久久久久亚洲精品杨幂换脸| 欧美大片免费| 国产欧美va欧美va香蕉在| 久久久精品国产一区二区三区| 99精品国产热久久91蜜凸| 午夜在线成人av| 激情成人综合| 国产精品成人一区二区艾草| 蘑菇福利视频一区播放| 国产精品推荐精品| 欧美日韩国产麻豆| 国产精品成人一区二区三区夜夜夜| 欧美国产综合一区二区| 国产一区二区日韩精品欧美精品| 在线观看国产一区二区| 国产精品羞羞答答xxdd| 亚洲国产中文字幕在线观看| 亚洲激情图片小说视频| 国内自拍视频一区二区三区| 中文亚洲免费| 国产精品福利久久久| 久久久亚洲影院你懂的| 亚洲精品国产精品乱码不99按摩| 国产综合久久| 欧美午夜一区二区福利视频| 欧美日韩精品在线视频| 欧美日韩亚洲一区在线观看| 亚洲图片欧美日产| 欧美 日韩 国产在线| 欧美大尺度在线| 精品51国产黑色丝袜高跟鞋| 欧美日韩一区二区在线观看| 99视频+国产日韩欧美| 一二三区精品福利视频| 91久久精品视频| 亚洲一区二区三区在线| 午夜免费久久久久| 亚洲七七久久综合桃花剧情介绍| av不卡免费看| 日韩亚洲欧美中文三级| 国产欧美一区二区精品秋霞影院| 国产精品伦一区| 亚洲天堂久久| 国产精品国产三级国产普通话蜜臀| 国产亚洲一本大道中文在线| 亚洲欧美在线视频观看| 国产精品高清网站| 激情懂色av一区av二区av| 国产一区二区三区高清播放| 日韩亚洲欧美成人| 欧美老女人xx| 欧美日韩免费区域视频在线观看| 久久国产精品久久久| 国产一区二区三区久久久久久久久| 99精品视频免费在线观看| 一本色道久久综合亚洲91| 国产偷国产偷精品高清尤物| 亚洲一区二区在线免费观看| 洋洋av久久久久久久一区| 欧美日韩在线三级| 国产一区二区三区丝袜| 国产欧美精品久久| 国产人妖伪娘一区91| 欧美午夜影院| 亚洲欧美日本伦理| 久久精品72免费观看| 欧美一区二区三区日韩视频| 欧美精品亚洲一区二区在线播放| 欧美精品一区二区在线播放| 欧美搞黄网站| 亚洲国产清纯| 国产婷婷色综合av蜜臀av| 一区二区视频免费在线观看| 伊人久久大香线蕉av超碰演员| 国产精品三上| 欧美一级大片在线免费观看| 在线视频国内自拍亚洲视频| 国产日韩欧美在线| 性高湖久久久久久久久| 久久色中文字幕| 欧美久久久久久久| 国产精品日韩二区| 一区在线免费观看| 性欧美8khd高清极品| 香蕉久久一区二区不卡无毒影院| 欧美丰满高潮xxxx喷水动漫| 欧美日韩亚洲免费| 国产专区欧美专区| 亚洲精品永久免费| 狠狠久久婷婷| 欧美大尺度在线观看| 亚洲精品资源美女情侣酒店| 亚洲五月婷婷| 在线综合欧美| 亚洲综合国产精品| 久久综合影音| 久久精品亚洲乱码伦伦中文| 99精品国产热久久91蜜凸| 免费在线欧美黄色| 国产精品欧美激情| 国内视频精品| 欧美日韩裸体免费视频| 亚洲国产成人av| 欧美韩国在线| 国产欧美日韩一区| 国产精品成人v| 日韩一级免费观看| 欧美成人一区二免费视频软件| 午夜精品区一区二区三| 99国产一区二区三精品乱码| 久久久久一区二区三区四区| 国产精品亚洲片夜色在线| 亚洲欧美精品在线观看| 亚洲精品国产精品乱码不99| 亚洲国产精品va在线观看黑人| 国产精品每日更新在线播放网址| 免费精品99久久国产综合精品| 亚洲一区二区三区四区五区黄| 国产视频自拍一区| 欧美激情精品久久久久久免费印度| 欧美专区第一页| 欧美日韩在线第一页| 久久av二区| 久久久欧美精品sm网站| 欧美成人自拍| 91久久嫩草影院一区二区| 欧美日产国产成人免费图片| 亚洲第一精品久久忘忧草社区| 在线天堂一区av电影| 亚洲区在线播放| 欧美高清不卡| 日韩一级在线| 久久免费99精品久久久久久| 国产欧美日韩免费看aⅴ视频| 欧美日一区二区三区在线观看国产免| 欧美体内谢she精2性欧美| 亚洲第一主播视频| 久久免费视频在线观看| 日韩视频一区二区三区| 欧美专区在线| 国产在线拍偷自揄拍精品| 欧美激情一级片一区二区| 久久免费99精品久久久久久| 亚洲欧美一区二区在线观看| 日韩视频在线永久播放| 亚洲欧美清纯在线制服| 欧美极品欧美精品欧美视频| 亚洲精品久久视频| 亚洲欧美国内爽妇网| 欧美日韩国产成人精品|