我对以下代码感到困惑,我在代码中写下了一些注释,指出了我的困惑。在代码的末尾有执行的结果,我还写下了我期望的结果。
package main
import (
"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
}
该规范说:
对于该语句中的所有情况,输入“ select”语句后,接收源的通道操作数以及send语句的通道表达式和右侧表达式将按源顺序被精确评估一次。结果是一组要从中接收或发送到的通道,以及要发送的相应值。不管选择进行哪个通信操作,都会发生该评估中的任何副作用。
goroutine A中用于select的通道组等待对的求值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秒钟。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句