首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >围棋漏水

围棋漏水
EN

Stack Overflow用户
提问于 2019-10-28 19:24:12
回答 1查看 867关注 0票数 1

在这篇关于例程泄漏( https://www.ardanlabs.com/blog/2018/11/goroutine-leaks-the-forgotten-sender.html )的文章之后,我试图解决我的代码泄漏问题.但是在通道中添加一个缓冲器,它并没有达到这个目的。

我的代码

代码语言:javascript
复制
package main

import (
    "fmt"
    "runtime"
    "time"
)

func main() {
    fmt.Println(runtime.NumGoroutine())
    leaking()
    time.Sleep(5)
    fmt.Println(runtime.NumGoroutine())
}

func leaking() {
    errChang := make(chan int, 1)
    go func() {
        xx :=  return666()
        errChang <- xx
    }()
    fmt.Println("hola")
    return

    fmt.Println(<-errChang)
}

func return666() int {
    time.Sleep(time.Second * 1)
    return 6
}

我的初始代码没有使用缓冲区,导致泄漏函数中的go例程..为了泄密。在帖子之后,我希望通过在通道中添加一个缓冲区,可以避免泄漏。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-10-28 21:46:36

在这里,在围棋游乐场是您的原始代码,只需稍作修改:

  • 除了time.Sleep(5)变成time.Sleep(time.Second)外,延迟也减少了;
  • return被删除,因为它变得没有必要;
  • fmt.Println被注释掉,因为对于return和未注释的fmt.Printlngo vet抱怨不可访问的fmt.Println
  • 存储在errChang中的信道将更改为无缓冲。

当运行时,它的输出是:

代码语言:javascript
复制
1
hola
2

(在2之前有一个小延迟),这表明您在函数leaking中启动的匿名goroutine仍然在运行。

如果我们使用fmt.Println,输出是:

代码语言:javascript
复制
1
hola
6
1

(在最后的1之前也有同样的轻微延迟),因为我们现在等待(然后打印)在return666中计算的值并通过通道errChang发送。

如果我们使用注释掉并使信道缓冲。,输出将变成:

代码语言:javascript
复制
1
hola
1

因为匿名的goroutine现在能够将它的值(6)推到通道中。

通道本身将与存储在其中的单个值一起被垃圾收集,因为此时不再有对通道的引用。但是,请注意,简单地使通道缓冲并不总是足够的。如果我们使用向通道发送两个值,程序将返回到打印:

代码语言:javascript
复制
1
hola
2

由于匿名的goroutine成功地将6放入了通道,但同时也阻止了试图将42放入通道。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58597199

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档