select select可以實現無阻塞的多通道嘗試讀寫,以及阻塞逾時
var c, c1, c2, c3
chanintvar i1, i2
int select {
case i1 = <-c1: //如果能走通任何case則隨機走一個
print( "received ", i1, " from c1\n" )
case c2 <- i2:
print( "sent ", i2, " to c2\n" )
case i3, ok := (<-c3):
if ok {
print( "received ", i3, " from c3\n" ) }
else {
print( "c3 is closed\n") }
default: // 如果case都阻塞,則走default,如果無default,則阻塞在case // default中可以不讀寫任何通道,那麼只要default提供不阻塞的出路,就相當於實現了對case的無阻塞嘗試讀寫
print( "no communication\n")}
實現阻塞逾時的方法是,只要不給default出路,而在case中實現一個逾時
timeout :=
make (
chanbool, 1)
gofunc () { time.Sleep(1e9) // 這是等待1秒鐘 timeout <-
true}() // 用timeout這個通道作為阻塞逾時的出路
select {
case <-ch: // 處理從ch中讀到的資料
case <-timeout: // 如果case都阻塞了,那麼1秒鐘後會從這裡找到出路}
range range可以在for迴圈中讀取channelGo文檔的翻譯文是:對於通道,其迭代值產生為在該通道上發送的連續值,直到該通道被關閉。若該通道為 nil,則range運算式將永遠阻塞經過實驗,range會阻塞,並且可以通過關閉channel來解除阻塞。
package main
import ( "fmt")
func main() { ch :=
make(
chanint )
gofunc () {
for i := 0; i < 10; i++ { ch <- i }
}()
for w :=
range ch { fmt.Println( "fmt print" , w)
if w > 5 { //break // 在這裡break迴圈也可以
close(ch) } } fmt.Println( "after range or close ch!" )}