以下代碼永遠運行,而不是在開始后一秒停止。帶有無限循環的 go 例程似乎阻止了另一個發送到超時通道。這是正常的嗎? func main(){ timeout:=make(chan int) go func(){ time.SLeep(time.Second) timeout<-1 }() res:=make(chan int) go func(){ for{ } res<-1 }() select{ case<-timeout: fmt.Println("timeout") case<-res: fmt.Println("res") }}
2 回答

SMILET
TA貢獻1796條經驗 獲得超4個贊
簡短的回答:是的。
當前的實現使用 goroutines 之間的協作調度。這意味著一個 goroutine 必須將執行移交給調度程序,以便另一個 goroutine 運行。將來有希望使用不會有此限制的搶占式調度程序。
當以下任何一種情況發生時,Goroutines 將讓給調度程序(可能不是一個完整的列表):
無緩沖的 chan 發送/接收
系統調用(包括文件/網絡讀寫)
內存分配
time.Sleep() 被調用
runtime.Gosched() 被調用
當您有一個非常處理器密集的循環時,最后一個允許您手動讓步給調度程序。我從來沒有發現需要它,因為我使用的幾乎所有東西都有足夠的通信(通道或系統 io),我的程序永遠不會卡住。
還有 GOMAXPROCS,您可能會聽到它作為解決方案。雖然它可以通過將所有 goroutine 放在不同的線程中來運行它們,但垃圾收集器最終會嘗試運行并停止世界。當它停止世界時,不允許任何 goroutines 運行,如果高 cpu goroutines 永遠不會讓步,GC 將永遠阻塞 goroutines 但永遠不會運行。
- 2 回答
- 0 關注
- 200 瀏覽
添加回答
舉報
0/150
提交
取消