为什么没有错误的接收器被阻塞?

Agnius Vasiliauskas:

根据Go文档

接收者总是阻塞直到有数据要接收

该测试应该失败,因为对于最后一次从通道接收操作,没有相应的写入:

package main

import "fmt"

func main() {
    c := make(chan int)    
    for i := 0; i < 4; i++ { // 4 async reads
      go func() {
            fmt.Println("received:", <-c)
         }()

    }    
    // just 3 writes, 1 write is missing
    c <- 1   
    c <- 2 
    c <- 3   
}

但是,脚本不会在读取goroutine中失败并显示错误消息,但是它可以成功打印3个值:

收到:1 
收到:2 
收到:3

为什么会这样,或者我对同步有误解?

icza:

这里没有死锁,因为maingoroutine没有被阻塞。它发送3个c成功的,因为有4个已启动的goroutine从那里接收,然后结束。有了它,您的应用程序也将结束,它不会等待其他非maingoroutine结束。请参阅goroutine没有输出

死锁意味着所有goroutine将被阻止。事实并非如此。

尝试从没有人(当前或曾经)准备好发送的频道接收消息不是错误。如果确实如此,那是完全正常的。那是渠道的用例之一:它充当同步工具,您可以发送/接收,并且操作将阻塞,直到另一端也准备就绪为止。

在某些情况下,甚至在整个应用程序生命周期内被阻止的goroutine都是正常的,例如goroutine可能会等待用户输入(例如CTRL+)BREAK,用户可能永远不会按下它,并且该应用可能会正常结束。

因此,这不被视为错误,并且不会为此打印任何错误或警告消息。但是,如果您好奇,可以轻松实现它。只需main()在您的main()函数(以及带有它的应用)结束之前向您添加一个延迟函数,函数将被称为最后一件事在该打印中,正在运行的goroutine数量:

func main() {
    defer func() {
        fmt.Println("Remaining goroutines:", runtime.NumGoroutine()-1) //-1 for main
    }()

    // your code
}

加上这个,输出将是:

received: 1
received: 2
received: 3
Remaining goroutines: 1

如果将循环更改为启动14个goroutine,而不是1,则输出将显示剩余11个goroutine。

最后说明:由于在您的应用中该main()函数不会等待其他goroutine结束,因此在调用延迟函数时它们可能仍处于活动状态,因此它们可能会或可能不会包含在其余goroutine计数中。如果您使用eg sync.WaitGroup等它们结束,那么它们肯定不会包含在内。有关示例,请参见防止main()函数在Goroutine在Golang中完成之前终止

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

为什么没有JDBC Spark Streaming接收器?

仅接收器应用程序停止 - 通道关闭(smfclient 2)没有错误

为什么我的广播接收器没有响应任何电话状态?

为什么指定方法接收器有时会触发“未定义”错误?

没有可用的EJB接收器

在浏览器的文件URL中输入许多斜杠时,为什么没有错误?

为什么我的GLSL着色器无法编译而没有错误消息?

为什么带有指针接收器的方法在接收值时仍然可以工作?

为什么下面的代码编译没有错误?

为什么“ std :: string(blablabla());” 编译没有错误?

广播接收器“接收”方法没有被调用吗?

为什么Flink仅具有Avro的keyValue接收器编写器?

为什么get.Handler中的console.log接收器值会导致错误?

Qt 错误:发出信号 QQmlEngine::quit(),但没有连接接收器来处理它

Ruby在没有显式接收器的情况下,什么类会获得方法?

如果信号线程被阻塞,为什么在接收线程中没有处理信号?

Tensorflow v1.10 +为什么在没有检查点的情况下需要输入服务接收器功能?

为什么接收器中的onReceive不被调用?

为什么IO.Writer无法填充接收器?

为什么我的收费接收器总是返回false?

广播接收器:为什么它不起作用?

为什么广播接收器不调用服务

为什么我的BroadCast接收器不起作用?

gstreamer没有刷新到文件接收器

没有接收器的流数据流管道

似乎SMS上的广播接收器没有触发

没有媒体的Chromecast自定义接收器

广播接收器没有收到消息

广播接收器没有收到额外信息