select語句不使用default分支時,處於阻塞狀態直到其中乙個channel的收/發操作準備就緒(或者channel關閉或者緩衝區有值),如果同時有多個channel的收/發操作準備就緒(或者channel關閉)則隨機選擇其中乙個。
select語句使用default分支時,處於非阻塞狀態,從所有準備就緒(或者channel關閉或者緩衝區有值)的channel中隨機選擇其中乙個,如果沒有則執行default分支。
嚴格來講,select的實現包括兩種順序:一是:輪詢順序(poll order),二是加鎖/解鎖順序(lock order)。個人理解,這道題的本意應該是在問輪詢順序。
輪詢順序的實現: 首先將所有case分支進行隨機排序,然後按照這個隨機順序來遍歷case分支,選擇第乙個符合條件(就緒或關閉或緩衝區有值)的channel即返回不再遍歷後面的case分支。
在 for switch 和 for select 的 block中,如果用了break
break出的是switch 和 select ,並不是break for
解決方法:
1 用 return
2 用 break tag
package main
import
"fmt"
func
main()
} fmt.
println
("out!"
)}
package main
import
("fmt"
"time"
)func
main()
(ch1)
gofunc
(c2 chan
int)
(ch2)
//等10毫秒,確保兩個channel都已準備就緒
time.
sleep(10
* time.millisecond)
var index int
select
} fmt.
printf
("cnt=%v\n"
, cnt)
}
out:
cnt=
[497 503]
可以看出總和為1000,而且比例接近1:1(隨機)
package main
import
("fmt"
"time"
)func
main()
} fmt.
printf
("cnt=%v\n"
, cnt)
}
out:
cnt=
[512 488]
由於等待時間的存在,select還是在兩個分支中進行隨機選擇,不走default流程;但是如果去掉等待時間,將變為
cnt=
[0 0]
package main
import
"fmt"
func
fibonacci
(c, quit chan
int)}}
func
main()
quit<-0}
()// 無快取channel通訊必須要在不同的goroutine中,否則無法滿足乙個產生乙個消費的同步原則
fibonacci
(c,quit)
}
out:
112
35813
2134
55quit
package main
import
"time"
import
."fmt"
func
main()
}()go
func()
}}()
<- o
}
該程式輸出0-99,過5s後列印出timeout Golang併發程式設計中select簡單了解
select可以監聽channel的資料流動 select的用法與switch語法非常類似,由select開始的乙個新的選擇塊,每個選擇條件由case語句來描述 與switch語句可以選擇任何使用相等比較的條件相比,select由比較多的限制,其中最大的一條限制就是每個case語句裡必須是乙個io操...
Go併發程式設計 select的使用
本文描述了select的用法,通過select可以監聽多個channel的讀寫事件。這很類似於linux系統程式設計的select函式。但在go中,實現的機制明顯是不同的。linux系統程式設計的select是輪訓的機制,而且監控的是檔案描述符,且有數量的限制。go中的select和channel配...
Golang併發模型 select高階
最近公司工作有點多,golang的select高階就這樣被拖沓啦,今天堅持把時間擠一擠,把吹的牛皮補上。前一篇文章 golang併發模型 輕鬆入門select 介紹了select的作用和它的基本用法,這次介紹它的3個高階特性。nil的通道永遠阻塞 如何跳出for selectselect 阻塞 當c...