为什么在此通道上选择了goroutine却阻止了写通道?

h

我对以下代码感到困惑,我在代码中写下了一些注释,指出了我的困惑。在代码的末尾有执行的结果,我还写下了我期望的结果。

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] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

为什么在此通道上不发送阻止?

在转到通道上选择内部范围

为什么通道上的常规程序块被视为死锁?

为什么要在此功能中使用通道?

在一个通道上监听多个goroutine

在通道上发送指针是否不安全?如果是,那为什么呢?

为什么生成在MPSC通道上迭代的线程的程序永远不会退出?

通道上的超时增加

选择通道<-<-通道

Golang:为什么增加缓冲通道的大小会消除goroutine的输出?

为什么从零通道读取会增加Goroutine的数量?

为什么在同一goroutine中使用未缓冲的通道会导致死锁?

为什么goroutine中的未缓冲通道得到了这个顺序

为什么golang中的select仅适用于goroutine中的通道?

为什么 Go 使用通道在 goroutine 之间发送和接收数据而不是使用普通变量?

Goroutine,通道和死锁

for循环中的goroutine通道

当我在发件人一侧关闭时,为什么仍会慌张地“在关闭的通道上发送”?

在通道上重复数组

通道上的cap()不是常数?

Bluestacks卡在加载通道上

如何在未知数目的goroutine提供的通道上阻塞(并加入)?

Golang Goroutine无法使用在通道上使用范围的功能运行延迟

为什么goroutine在此http服务器中阻止main func?

了解使用和不使用goroutine的通道中的选择

为什么在使用select并将值依次馈入2个通道时,所有goroutine都处于睡眠状态?

为什么通道类型中带有“ <-”?

为什么基于通道的锁定块?

为什么通道的方向变化不兼容?