【问题标题】:goroutine leak with buffered channel in GoGo中带有缓冲通道的goroutine泄漏
【发布时间】:2018-02-18 20:21:48
【问题描述】:

以下代码使用 Go 编程语言

func mirroredQuery() string {
    responses := make(chan string, 3)
    go func() { responses <- request("asia.gopl.io") }()
    go func() { responses <- request("europe.gopl.io") }()
    go func() { responses <- request("americas.gopl.io") }()
    return <-responses // return the quickest response
}

func request(hostname string) (response string) { /* ... */ }

书上说

如果我们使用无缓冲通道,则两个通道会变慢 goroutines 在尝试发送响应时会卡住 在一个 goroutine 永远不会接收到的通道上。这种情况,称为 goroutine 泄漏,将是一个错误。不像垃圾 变量,泄漏的 goroutine 不会自动收集,所以 确保 goroutine 自行终止很重要 不再需要时。


问题是为什么这种情况会导致goroutine泄漏。在我的想法中,缓冲通道的cap是3,而3goroutines将发送他们的请求并立即退出,这不会导致泄漏。

【问题讨论】:

    标签: go


    【解决方案1】:

    显示的代码不会导致泄漏。

    正如段落所述:

    如果我们使用了无缓冲通道

    含义:如果我们使用了无缓冲通道...

    所以只有当通道没有缓冲时才会发生泄漏。

    【讨论】:

    • @eugenjoy 在缓冲通道的情况下,为什么两个较慢的 goroutine 不会尝试将它们的响应发送到通道?可能存在这样一种情况,在其中一个 goroutine 发送其请求之前,已收到对此“ 的响应
    • @rnjai :较慢的 goroutine 确实会尝试将响应发送到通道。没有人会真正读取这些响应,但这不是问题,因为通道的缓冲区大小为 3,因此可以将响应容纳在缓冲区中,这样 goroutines 就不会阻塞。
    • 是的,@eugenioy goroutines 肯定不会阻塞,但是肯定会有 goroutine 泄漏的范围,因为发送到没有接收器的通道会导致泄漏 - play.golang.org/p/vMKwqoACGfT
    • 嗨@rnjai,我不认为你的测试是正确的..尝试改变你的周期运行它 100 次并看看输出.. goroutines 的数量保持稳定并且不会增长随着时间的推移:play.golang.org/p/2DwtFkey53l
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-17
    • 2018-10-02
    • 2018-04-15
    • 2021-12-25
    相关资源
    最近更新 更多