abstract:channel go語(yǔ)言提供的消息通信機(jī)制被稱為channel. "不要通過(guò)共享內(nèi)存來(lái)通信,而應(yīng)該通過(guò)通信來(lái)共享內(nèi)存". channel是go語(yǔ)言在語(yǔ)言級(jí)別提供的goroutine之間的通信方式.是類型相關(guān)的,一個(gè)channel只能傳遞一種類型的值.這個(gè)類型需要在聲明channel的時(shí)候指定. 在對(duì)應(yīng)的channel被讀取前,這個(gè)操作時(shí)阻塞的,在所有的goroutine
channel
go語(yǔ)言提供的消息通信機(jī)制被稱為channel.
"不要通過(guò)共享內(nèi)存來(lái)通信,而應(yīng)該通過(guò)通信來(lái)共享內(nèi)存".
channel是go語(yǔ)言在語(yǔ)言級(jí)別提供的goroutine之間的通信方式.是類型相關(guān)的,一個(gè)channel只能傳遞一種類型的值.這個(gè)類型需要在聲明channel的時(shí)候指定.
在對(duì)應(yīng)的channel被讀取前,這個(gè)操作時(shí)阻塞的,在所有的goroutine啟動(dòng)完成后,我們通過(guò)<-ch語(yǔ)句從10個(gè)channel中依次讀取數(shù)據(jù),在對(duì)應(yīng)的channel寫入數(shù)據(jù)前,這個(gè)操作也是阻塞的.這樣我們就用channel實(shí)現(xiàn)了類似鎖的功能,進(jìn)而保證了所有的goroutine完成后主函數(shù)才能返回.
go demo package main import ( "fmt" "runtime" ) func Count(ch chan int, i int) { fmt.Println("counting", i) ch <- i fmt.Println("after chan", i) } func main() { runtime.GOMAXPROCS(runtime.NumCPU()) chs := make([]chan int, 10) for i := 0; i < 10; i++ { chs[i] = make(chan int) go Count(chs[i], i) } fmt.Println("start for") for _, ch := range chs { var ii int ii = <-ch fmt.Println("for ", ii) } }
select
go語(yǔ)言直接在語(yǔ)言級(jí)別支持select關(guān)鍵字,用于處理異步IO問(wèn)題.
select 用法與switch類似,最大的一條限制是每個(gè)case語(yǔ)句必須是一個(gè)IO操作,case后都必須是chan操作
select{ case <-chan1: // 如果成功從chan1成功數(shù)據(jù) case chan2<-1: // 如果成功向chan2寫入數(shù)據(jù) default: //如果都沒(méi)成功 } // 隨機(jī)寫入 0,1 ch := make(chan int, 1) for a := 0; a < 10; a++ { select { case ch <- 0: case ch <- 1: } i := <-ch fmt.Println(i)
緩沖機(jī)制
使用于需要持續(xù)傳輸大量數(shù)據(jù)的場(chǎng)景, c := make(chan int ,1024),即使沒(méi)有讀取方,寫入方也可以一直往channel里寫入,在緩沖區(qū)填完之前不會(huì)被阻塞.
從緩沖區(qū)讀取數(shù)據(jù)與常規(guī)非緩沖channel完全一致,我們也可以使用range關(guān)鍵字來(lái)實(shí)現(xiàn)循環(huán)讀取
超時(shí)機(jī)制
在往channel寫入數(shù)據(jù)時(shí)發(fā)現(xiàn)已滿,或讀取數(shù)據(jù)時(shí)發(fā)現(xiàn)為空,如果不正確處理這些數(shù)據(jù),很可能導(dǎo)致整個(gè)goroutine死鎖.
可以結(jié)合select 進(jìn)行超時(shí)處理.
channel 包括 雙向channel,單項(xiàng)channel(只讀channel,只寫channel)
關(guān)閉channel
close(ch);判斷關(guān)閉 x,ok := <-ch 只需要判斷第二個(gè)bool返回值即可.false則表示關(guān)閉.