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

当主/父 goroutine 退出或返回时,未完成的 goroutine 会发生什么?

当主/父 goroutine 退出或返回时,未完成的 goroutine 会发生什么?

Go
饮歌长啸 2022-12-19 20:04:53
我正在阅读 go programming language 书,第 8.4 章中有这个例子func mirroredQuery() string{    responses := make(chan string, 3)    go func() { responses <- request("asia.gopl.io") }()    go func() { responses <- request("americas.gopl.io") }()    go func() { responses <- request("europe.gopl.io") }()    return <- responses // return the quickest response}还有这个评论如果我们使用一个无缓冲的通道,那么两个较慢的 goroutines 会卡住试图在一个没有 goroutine 接收到的通道上发送它们的响应。这个评论本身是有道理的。但是mirroredQuery在缓冲情况下返回时两个慢 goroutine 会发生什么?他们是否仍然跑完或被取消?编辑:我知道如果主要的 goroutnine 退出,那么无论它们是否运行,2 个较慢的 goroutines 都会“消失”。但是如果 main goroutine 还在运行,mirroredQuery()已经返回了,那 2 个 slow goroutines 会跑完吗?基本上,退货responses后还存在吗?mirroredQuery如果是这样,那么 2 个慢 goroutine 似乎原则上可以完成;如果不是,那么我们仍然像无缓冲情况一样有泄漏?
查看完整描述

1 回答

?
幕布斯7119047

TA贡献1794条经验 获得超8个赞

当主goroutine 返回时,整个运行时系统退出,相当突然。因此,任何卡在无缓冲或完整通道上等待发送的 goroutines 都将……不复存在。它们不会取消,不会运行,也不会等待。 把它想象成闪光纸着火了。


可以将此称为 goroutine 泄漏,就像在程序终止“泄漏”之前可以引用任何未关闭或释放的资源(例如打开的文件)一样。但是由于整个过程终止,所以什么都没有了。这里没有真正的泄漏。这不是一个整洁的清理,但系统确实清理了。


作为示例,这是一个游乐场链接。


(如果你使用 Go 系统本身没有定义的东西,你可能会以这种方式出现各种泄漏。例如,在旧的 System V 共享内存世界中,你可以创建共享内存段(shm_open)并且如果你从不关闭和取消链接他们,他们坚持。这是设计使然:他们的行为很像文件系统中的文件,只是它们存在于内存中,而不是存在于某种磁盘驱动器或其他任何东西上。但这远远超出了日常生活的正常范围去编程。)


重新编辑:如果主goroutine没有退出,所以程序仍在运行,其他 goroutines 继续运行(或等待)直到他们用完所有事情并返回自己,或者做一些导致他们退出的事情(比如打电话runtime.Goexit,或者做一些引起恐慌的事情)。在这种情况下,就是:等待响应,然后将响应发送到通道中,然后返回。假设他们得到响应,他们会将响应放入通道中。假设将响应放入通道有效(不恐慌也不阻塞),然后它们将返回。回来后,他们完成了,他们蒸发了。通道本身持续存在并持有字符串:这是资源泄漏,尽管是次要的,尤其是在玩具程序中。


如果没有对通道本身的引用,则通道本身以及其中的字符串将被垃圾回收;这清理了泄漏的资源。由于我们假设它mirroredQuery已经返回,并且此时最后一个分离出来的 goroutine 也已经返回,这是对通道的最后引用,所以现在可以对通道进行 GC。(这种情况是否发生以及何时发生取决于运行时。)在这些 goroutine 中的最后一个完成之前,仍然至少有一个对通道的引用,从而阻止通道(以及字符串)被 GC。


如果通道是无缓冲的,那么两个“丢失”的 goroutine 将阻止发送到通道的尝试。这将导致那些 goroutines 保留下来,这反过来又会导致通道保留下来,这又会导致资源保持分配状态,直到程序作为一个整体终止。所以那将是“坏的”。


关闭通道后,两个“失败”的 goroutine 可能会尝试在关闭的通道上发送mirroredQuery ,这将导致它们调用恐慌代码,从而终止程序。那也将是“坏的”。实现预期结果的最简单代码是使通道缓冲。


如果其中一个 goroutine 等待(响应)数年,那么这些年将保留那些“泄漏”的资源。这也将是“坏的”(轻微),所以我们想确保他们不会永远等待。但这在小型演示程序中是不切实际的。


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

添加回答

举报

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