2023-05-27 Go協(xié)程goroutine與通道channel

理解go與channel的關(guān)系

sync.WaitGroup

使用sync.WaitGroup等待一組并發(fā)操作完成。

var wg sync.WaitGrop
func hello(i int){
    defer wg.Done()
    fmt.Println("hello",i)
}
func main(){
    for i:=0;i<10;i++{
        wg.Add(1)
        go hello(i)
    }
    wg.Wait()  //在這里阻塞等待go結(jié)束
    fmt.Println("hello world")
}

channel 管道

通道的作用是用于兩個(gè)協(xié)程之間的通信:

分類:

無(wú)緩沖channel木缝;

有緩沖channel我碟。

//整形無(wú)緩沖通道
unbuffered := make(chan int)
//整形有緩沖通道
buffered := make(chan int 10)

功能:

無(wú)緩存通常用于同步通信

有緩存通常用于異步通信

語(yǔ)法:

//整形無(wú)緩沖通道
unbuffered := make(chan int)
//整形有緩沖通道
buffered := make(chan int 10)

//無(wú)緩沖管道使用
ch1 := make(chan string)  //初始化一個(gè)無(wú)緩沖字符串管道
ch1 <- "hello world"        //發(fā)送數(shù)據(jù)到管道(在這里就阻塞了)
data :=<- ch1               //從管道接受數(shù)據(jù)
close(ch1)                  //關(guān)閉管道

//有緩沖管道使用
    //情況1:讀取堵塞
  ch1 := make(chan int,5)  //大小為5的管道
  ch1 <- 10         //發(fā)送數(shù)據(jù)到管道
  ch1 <- 20       //發(fā)送數(shù)據(jù)到管道
  data :=<- ch1                     //從管道接受數(shù)據(jù)
  data2 :=<-ch1               //從管道接受數(shù)據(jù)
  data3 :=<- ch1
  fmt.Printf("data: %v\n", data)  
  fmt.Printf("data2: %v\n", data2)
  fmt.Printf("data3: %v\n", data3)  //因?yàn)楣艿乐兄挥?個(gè)數(shù)據(jù)矫俺,讀取第三個(gè)時(shí)會(huì)阻塞
  close(ch1)
    //情況2:發(fā)送阻塞
  ch1 := make(chan int,1)  //大小為1的管道
  ch1 <- 10         //發(fā)送數(shù)據(jù)到管道
  ch1 <- 20       //發(fā)送第二個(gè)數(shù)據(jù)到管道時(shí)會(huì)阻塞掸冤,因?yàn)楣艿赖拇笮≈挥?
  data :=<- ch1                     //從管道接受數(shù)據(jù)
  fmt.Printf("data: %v\n", data)
  close(ch1)
    //情況三:無(wú)阻塞
  ch1 := make(chan int,5)  //字符串管道
  ch1 <- 10         //發(fā)送數(shù)據(jù)到管道
  ch1 <- 20       //發(fā)送數(shù)據(jù)到管道
  data :=<- ch1                     //從管道接受數(shù)據(jù)
  data2 :=<-ch1               //從管道接受數(shù)據(jù)
  fmt.Printf("data: %v\n", data)
  fmt.Printf("data2: %v\n", data2)
  close(ch1)

goroutine與channel

for range從channel中取值

當(dāng)通道被關(guān)閉后稿湿,會(huì)在通道內(nèi)的所有值被接收完畢后會(huì)自動(dòng)退出循環(huán)。ps:如果沒(méi)有關(guān)閉通道會(huì)死鎖饺藤。

package main
import (
    "fmt"
    "sync"
)
var wg sync.WaitGroup
func f1(ch chan int){
  defer wg.Done()
  for x:=range ch{  //不斷地從管道讀取數(shù)據(jù),直到管道被關(guān)閉舰始,如果管道沒(méi)有被關(guān)閉咽袜,會(huì)無(wú)法退出造成死鎖
    fmt.Println(x)
  }
}
func main() {
  ch := make(chan int,10)
  wg.Add(1)
  go f1(ch)
  for i:=0;i<11;i++ {
    ch<-i
  }
  close(ch)    //這里不關(guān)閉管道會(huì)死鎖
  wg.Wait()
}

當(dāng)通道被關(guān)閉后询刹,依舊可以從通道中讀取數(shù)據(jù),如果通道中已經(jīng)沒(méi)有數(shù)據(jù)那么會(huì)讀到0值沐兰。

func main() {
  ch := make(chan int,2)
  ch<-10
  ch<-20
  close(ch)         
  //關(guān)閉管道后依然可以讀到管道內(nèi)的數(shù)據(jù)蔽挠,for range只會(huì)讀去管道存在的數(shù)據(jù)
  for x:=range ch { 
    fmt.Printf("x: %v\n", x)
  }
  //關(guān)閉了管道依然可以讀,管道沒(méi)有數(shù)據(jù)了比原,就會(huì)讀到0值,ok==false
  x杠巡,ok:=<-ch
  fmt.Printf("x: %v\n", x)
  fmt.Printf("ok: %v\n", ok)
}

select

select可以從多個(gè)通道接收值,使用它可以同時(shí)響應(yīng)多個(gè)通道的操作蚌铜。

每個(gè) case 分支會(huì)對(duì)應(yīng)一個(gè)通道的通信(接收或發(fā)送)過(guò)程嫩海。select 會(huì)一直等待,直到其中的某個(gè) case 的通信操作完成時(shí)造壮,就會(huì)執(zhí)行該 case 分支對(duì)應(yīng)的語(yǔ)句骂束。

select 具有以下特點(diǎn):

  • 處理一個(gè)或多個(gè) channel 的發(fā)送/接收操作

  • 如果多個(gè) case 同時(shí)滿足旨枯,select 會(huì)隨機(jī)選擇一個(gè)執(zhí)行混驰。

  • 對(duì)于沒(méi)有 case 的 select 會(huì)一直阻塞皂贩,可用于阻塞 main 函數(shù)昆汹,防止退出满粗。

    ch := make(chan int, 1)
    for i := 1; i <= 10; i++ {
        select {  //select處理的是一個(gè)發(fā)送或者讀取操作,如下對(duì)同一個(gè)管道的兩個(gè)不同操作映皆。
            case x := <-ch:
              fmt.Println(x)
            case ch <- i:
            }
    }
    

select用于處理異步IO操作總結(jié)

1.select 會(huì)監(jiān)聽(tīng)case語(yǔ)句中的讀寫操作捅彻,當(dāng)case中的channel讀寫操作為非阻塞狀態(tài),將會(huì)觸發(fā)相應(yīng)的動(dòng)作从隆。

2.如果有多個(gè)case可以執(zhí)行缭裆,select會(huì)隨機(jī)公平地選出一個(gè)執(zhí)行,其他不會(huì)執(zhí)行艾杏。

3.如果沒(méi)有可執(zhí)行地case語(yǔ)句盅藻,且有default語(yǔ)句,就會(huì)執(zhí)行default語(yǔ)句勃蜘。

4.如果沒(méi)有可運(yùn)行地case語(yǔ)句假残,且沒(méi)有default語(yǔ)句,select將阻塞阳惹,直到有case能執(zhí)行眶俩。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末颠印,一起剝皮案震驚了整個(gè)濱河市抹竹,隨后出現(xiàn)的幾起案子止潮,更是在濱河造成了極大的恐慌,老刑警劉巖兢孝,帶你破解...
    沈念sama閱讀 216,997評(píng)論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異雳殊,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)座咆,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,603評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門介陶,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)色建,“玉大人,你說(shuō)我怎么就攤上這事某残×晡” “怎么了?”我有些...
    開(kāi)封第一講書人閱讀 163,359評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵澳厢,是天一觀的道長(zhǎng)剩拢。 經(jīng)常有香客問(wèn)我饶唤,道長(zhǎng),這世上最難降的妖魔是什么搬素? 我笑而不...
    開(kāi)封第一講書人閱讀 58,309評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮谓罗,結(jié)果婚禮上季二,老公的妹妹穿的比我還像新娘。我一直安慰自己刻蚯,他們只是感情好桑嘶,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,346評(píng)論 6 390
  • 文/花漫 我一把揭開(kāi)白布逃顶。 她就那樣靜靜地躺著,像睡著了一般以政。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上废菱,一...
    開(kāi)封第一講書人閱讀 51,258評(píng)論 1 300
  • 那天,我揣著相機(jī)與錄音抖誉,去河邊找鬼昙啄。 笑死,一個(gè)胖子當(dāng)著我的面吹牛寸五,可吹牛的內(nèi)容都是我干的梳凛。 我是一名探鬼主播,決...
    沈念sama閱讀 40,122評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼梳杏,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼韧拒!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起十性,我...
    開(kāi)封第一講書人閱讀 38,970評(píng)論 0 275
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤叛溢,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后楷掉,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,403評(píng)論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡霞势,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,596評(píng)論 3 334
  • 正文 我和宋清朗相戀三年烹植,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了斑鸦。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,769評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡草雕,死狀恐怖巷屿,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情墩虹,我是刑警寧澤嘱巾,帶...
    沈念sama閱讀 35,464評(píng)論 5 344
  • 正文 年R本政府宣布,位于F島的核電站诫钓,受9級(jí)特大地震影響旬昭,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜菌湃,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,075評(píng)論 3 327
  • 文/蒙蒙 一问拘、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧慢味,春花似錦、人聲如沸墅冷。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 31,705評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)寞忿。三九已至驰唬,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間腔彰,已是汗流浹背叫编。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 32,848評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留霹抛,地道東北人搓逾。 一個(gè)月前我還...
    沈念sama閱讀 47,831評(píng)論 2 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像杯拐,于是被迫代替她去往敵國(guó)和親霞篡。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,678評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容