我对以下代码感到困惑,我在代码中写下了一些注释,指出了我的困惑。并且在代码的最后有一个执行结果,我也写下了我期望的结果。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 关注
- 95 浏览
添加回答
举报
0/150
提交
取消