golang channel 的使用
阿新 • • 發佈:2017-12-03
參考 mark log port 準備 lan mar case .com
本文對channel使用中的幾個疑惑,以例子的形式加以說明。
普通channel
缺省情況下,發送和接收會一直阻塞著,直到另一方準備好.
例如:
package main import ( "fmt" "time" ) var ch1 chan bool func main(){ ch1 = make(chan bool) go reader() go writer() select { } } func writer() { time.Sleep(10*time.Second) for { ch1 <- true fmt.Println("write one ...") } } func reader() { for { select { case <-ch1: fmt.Println("read one ....") } time.Sleep(2*time.Second) } }
output:
$ ./chan1.exe
write one ...
read one ....
read one ....
write one ...
read one ....
write one ...
read one ....
write one ...
從執行結果看,reader卡住,直到writer sleep後就位,才繼續執行。反之,讓reader先睡眠,writer也會卡住,直到reader sleep後就位。
帶buffer的channel
帶buffer的channel可以減少阻塞,對一些需要只保持有限個執行過程的情景很有用。
例1:
// reader wait, until writer begin to write. package main import ( "fmt" "time" ) var ch1 chan bool func main(){ ch1 = make(chan bool, 1) go reader() go writer() select { } } func writer() { time.Sleep(10*time.Second) for { ch1 <- true fmt.Println("write one ...") } } func reader() { for { select { case <-ch1: fmt.Println("read one ....") } time.Sleep(2*time.Second) } }
這種情景中,先讓writer睡眠,reader此時卡住,直到writer就位,也就是說,帶buffer,如果沒有數據寫入,reader也是卡住的。
例2:
// writer write one, then wait package main import ( "fmt" "time" ) var ch1 chan bool func main(){ ch1 = make(chan bool, 1) go reader() go writer() select { } } func writer() { for { ch1 <- true fmt.Println("write one ...") } } func reader() { time.Sleep(10*time.Second) for { select { case <-ch1: fmt.Println("read one ....") } time.Sleep(2*time.Second) } }
如果先讓reader睡眠,writer直接向channel寫,可以看到writer可以寫入一個數據,然後卡住,直到reader就位,才可以繼續寫。
也就是說,帶一個buffer的channel,可以在reader就位前首先寫入一個數據。
參考
http://colobu.com/2016/04/14/Golang-Channels/
golang channel 的使用