我對以下代碼感到困惑,我在代碼中寫下了一些注釋,指出了我的困惑。并且在代碼的最后有一個執行結果,我也寫下了我期望的結果。package mainimport ( "fmt" "time")func sendRPC() bool { time.Sleep(5 * time.Second) return true}func main() { done := make(chan struct{}) ch := make(chan bool) go func() { // goroutine A select { case ch <- sendRPC(): fmt.Println("RPC return") case <-done: fmt.Println("exit") } }() select { case <-ch: case <-time.After(1000 * time.Millisecond): fmt.Println("timeout") if len(done) == 0 { fmt.Println("1") // here write done channel will block until sendRPC() return, why? // I expect that the write is nonblock because goroutine A is select on done channel. done <- struct{}{} fmt.Println("2") } } // result: // timeout (after about 1 second) // 1 // exit (after about 5 seconds, I expect that it is printed after about 1 second too.) // 2}
1 回答

繁星coding
TA貢獻1797條經驗 獲得超4個贊
規范說:
對于語句中的所有情況,接收操作的通道操作數以及發送語句的通道和右側表達式在輸入“select”語句時按源順序恰好計算一次。結果是一組要從中接收或發送到的通道,以及要發送的相應值。無論選擇哪個(如果有的話)通信操作繼續進行,該評估中的任何副作用都會發生。
goroutine A 中選擇的通道集等待對 的求值sendRPC()
。查看這個等效的 goroutine 可能會有所幫助:
go func() { // goroutine A
? ? v := sendRPC()? // waits for 5 seconds
? ? select {
? ? case ch <- v:
? ? ? ? fmt.Println("RPC return")
? ? case <-done:
? ? ? ? fmt.Println("exit")
? ? }
}()
接收done延遲 5 秒。
- 1 回答
- 0 關注
- 119 瀏覽
添加回答
舉報
0/150
提交
取消