Go語言學習-channal

channal

channel是Go語言在語言級別提供的goroutine間的通信方式筏勒,是一種進程內(nèi)的通信方式沐旨。
在Go中,goroutine和channel是并發(fā)編程的兩大基石,goroutine用來執(zhí)行并發(fā)任務耘斩,channel用來在goroutine之間來傳遞消息。


channal數(shù)據(jù)結(jié)構(gòu)

type hchan struct {
    qcount   uint           // total data in the queue桅咆;chan中的元素總數(shù)
    dataqsiz uint           // size of the circular queue括授;底層循環(huán)數(shù)組的size
    buf      unsafe.Pointer // points to an array of dataqsiz elements,指向底層循環(huán)數(shù)組的指針岩饼,只針對有緩沖的channel
    elemsize uint16  //chan中元素的大小
    closed   uint32  //chan是否關閉
    elemtype *_type // element type荚虚;元素類型
    sendx    uint   // send index;已發(fā)送元素在循環(huán)數(shù)組中的索引
    recvx    uint   // receive index籍茧;已接收元素在循環(huán)數(shù)組中的索引
    recvq    waitq  // list of recv waiters版述,等待接收消息的goroutine隊列
    sendq    waitq  // list of send waiters眼俊,等待發(fā)送消息的goroutine隊列

    // 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
}

緩沖通道

channal基本特征:

  1. 對于同一個通道岳服,發(fā)送操作之間是互斥的操骡,接收操作之間也是互斥的蒋歌。
  2. 發(fā)送操作和接收操作中對元素值的處理都是不可分割的拦止。
  3. 發(fā)送操作在完全完成之前會被阻塞哩照。接收操作也是如此弧烤。

通俗的講就是元素值被完全復制進該通道之后涧黄,其他針對該通道的發(fā)送操作才可能被執(zhí)行漓帚。元素值完全被移出該通道之后母债,其他針對該通道的接收操作才可能被執(zhí)行

  1. 發(fā)送操作包括了“復制元素值”和“放置副本到通道內(nèi)部”這兩個步驟。
  2. 接收操作通常包含了“復制通道內(nèi)的元素值”“放置副本到接收方”“刪掉原值”三個步驟

channal通道滿場景

  1. 發(fā)送操作在這種情況下被阻塞后胰默,所有發(fā)送操作所在的 goroutine 會順序地進入通道內(nèi)部的發(fā)送等待隊列场斑,所以通知的順序總是公平的。

channal通道空場景

接受操作在這種情況下被阻塞后牵署,所有接收操作所在的 goroutine漏隐,都會按照先后順序被放入通道內(nèi)部的接收等待隊列,接受一樣公平奴迅。


非緩沖通道

  1. 發(fā)送操作以及接受操作一開始就會被阻塞青责。直到發(fā)送接受這一對操作均執(zhí)行挺据。收發(fā)雙方對接上了,就可以傳遞數(shù)據(jù)脖隶。
  2. 數(shù)據(jù)直接由發(fā)送方復制到接受方扁耐,中間不需要使用非緩沖通道做中轉(zhuǎn)。

差異性

緩沖通道:異步傳送數(shù)據(jù)
非緩沖通道:同步傳送數(shù)據(jù)


channal錯誤使用場景

  1. 對于值為nil的通道产阱,不論他的類型是什么婉称,對他進行發(fā)送或者接受操作都會處于阻塞狀態(tài)。
  2. 對于關閉的channal發(fā)送數(shù)據(jù)會發(fā)生panic
  3. 試圖關閉已經(jīng)關閉的channal會觸發(fā)panic

注意:不要讓接受方關閉通道构蹬,盡量讓發(fā)送方來關閉


單項通道

應用價值:單向通道最主要的用途就是約束其他代碼的行為王暗。

range 遍歷channal


func getIntChan() <-chan int {
  num := 5
  ch := make(chan int, num)
  for i := 0; i < num; i++ {
    ch <- i
  }
  close(ch)
  return ch
}


intChan2 := getIntChan()
for elem := range intChan2 {
  fmt.Printf("The element in intChan2: %v\n", elem)
}
  1. for range 能夠從 channal中取出元素值,及時channal關閉也能夠讀取剩余所有元素之后結(jié)束庄敛。
  2. 如果channal沒有關閉俗壹,channal為空時for range會阻塞直到有新的元素可取,當close channal藻烤,for循環(huán)直接結(jié)束绷雏。
  3. 如果 channal為nil會永久阻塞

select

select語句的分支分為兩種,一種叫做候選分支怖亭,另一種叫做默認分支

  1. 如果像上述示例那樣加入了默認分支涎显,那么無論涉及通道操作的表達式是否有阻塞,select語句都不會被阻塞依许。如果那幾個表達式都阻塞了棺禾,或者說都沒有滿足求值的條件缀蹄,那么默認分支就會被選中并執(zhí)行峭跳。
  2. 如果沒有加入默認分支,那么一旦所有的case表達式都沒有滿足求值條件缺前,那么select語句就會被阻塞蛀醉。直到至少有一個case表達式滿足條件為止。
  3. select語句只能對其中的每一個case表達式各求值一次衅码。所以拯刁,如果我們想連續(xù)或定時地操作其中的通道的話,就往往需要通過在for語句中嵌入select語句的方式實現(xiàn)逝段。
  4. 如果select語句發(fā)現(xiàn)同時有多個候選分支滿足選擇條件垛玻,那么它就會用一種偽隨機的算法在這些分支中選擇一個并執(zhí)行。注意奶躯,即使select語句是在被喚醒時發(fā)現(xiàn)的這種情況帚桩,也會這樣做。
最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末嘹黔,一起剝皮案震驚了整個濱河市账嚎,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖郭蕉,帶你破解...
    沈念sama閱讀 222,946評論 6 518
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件疼邀,死亡現(xiàn)場離奇詭異,居然都是意外死亡召锈,警方通過查閱死者的電腦和手機旁振,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,336評論 3 399
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來涨岁,“玉大人规求,你說我怎么就攤上這事÷训耄” “怎么了阻肿?”我有些...
    開封第一講書人閱讀 169,716評論 0 364
  • 文/不壞的土叔 我叫張陵,是天一觀的道長沮尿。 經(jīng)常有香客問我丛塌,道長,這世上最難降的妖魔是什么畜疾? 我笑而不...
    開封第一講書人閱讀 60,222評論 1 300
  • 正文 為了忘掉前任赴邻,我火速辦了婚禮,結(jié)果婚禮上啡捶,老公的妹妹穿的比我還像新娘姥敛。我一直安慰自己,他們只是感情好瞎暑,可當我...
    茶點故事閱讀 69,223評論 6 398
  • 文/花漫 我一把揭開白布彤敛。 她就那樣靜靜地躺著,像睡著了一般了赌。 火紅的嫁衣襯著肌膚如雪墨榄。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,807評論 1 314
  • 那天勿她,我揣著相機與錄音袄秩,去河邊找鬼。 笑死逢并,一個胖子當著我的面吹牛之剧,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播砍聊,決...
    沈念sama閱讀 41,235評論 3 424
  • 文/蒼蘭香墨 我猛地睜開眼背稼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了辩恼?” 一聲冷哼從身側(cè)響起雇庙,我...
    開封第一講書人閱讀 40,189評論 0 277
  • 序言:老撾萬榮一對情侶失蹤谓形,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后疆前,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體寒跳,經(jīng)...
    沈念sama閱讀 46,712評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,775評論 3 343
  • 正文 我和宋清朗相戀三年竹椒,在試婚紗的時候發(fā)現(xiàn)自己被綠了童太。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,926評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡胸完,死狀恐怖书释,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情赊窥,我是刑警寧澤爆惧,帶...
    沈念sama閱讀 36,580評論 5 351
  • 正文 年R本政府宣布,位于F島的核電站锨能,受9級特大地震影響扯再,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜址遇,卻給世界環(huán)境...
    茶點故事閱讀 42,259評論 3 336
  • 文/蒙蒙 一熄阻、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧倔约,春花似錦秃殉、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,750評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至乒省,卻和暖如春巧颈,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背袖扛。 一陣腳步聲響...
    開封第一講書人閱讀 33,867評論 1 274
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留十籍,地道東北人蛆封。 一個月前我還...
    沈念sama閱讀 49,368評論 3 379
  • 正文 我出身青樓,卻偏偏與公主長得像勾栗,于是被迫代替她去往敵國和親惨篱。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,930評論 2 361