为了账号安全,请及时绑定邮箱和手机立即绑定

尽管在这个通道上选择了一个 goroutine,为什么写通道被阻塞了?

尽管在这个通道上选择了一个 goroutine,为什么写通道被阻塞了?

Go
白衣染霜花 2023-06-19 15:49:52
我对以下代码感到困惑,我在代码中写下了一些注释,指出了我的困惑。并且在代码的最后有一个执行结果,我也写下了我期望的结果。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 秒。


查看完整回答
反对 回复 2023-06-19
  • 1 回答
  • 0 关注
  • 95 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信