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

当非阻塞 readline 挂起时泄漏 goroutine

当非阻塞 readline 挂起时泄漏 goroutine

Go
千万里不及你 2021-11-08 16:51:02
假设你有这样的结构:ch := make(chan string)errCh := make(chan error)go func() {    line, _, err := bufio.NewReader(r).ReadLine()    if err != nil {        errCh <- err    } else {        ch <- string(line)    }}()select {case err := <-errCh:    return "", errcase line := <-ch:    return line, nilcase <-time.After(5 * time.Second):    return "", TimeoutError}在 5 秒超时的情况下,goroutine 会挂起,直到 ReadLine 返回,这可能永远不会发生。我的项目是一个长期运行的服务器,所以我不想要卡住的 goroutines 的积累。
查看完整描述

1 回答

?
Smart猫小萌

TA贡献1911条经验 获得超7个赞

ReadLine 在进程退出或方法读取一行之前不会返回。管道没有截止日期或超时机制。


如果对 ReadLine 的调用在超时后返回,goroutine 将阻塞。这可以通过使用缓冲通道来解决:


ch := make(chan string, 1)

errCh := make(chan error, 1)

应用程序应该调用Wait来清理与命令关联的资源。goroutine 是调用它的好地方:


go func() {

  line, _, err := bufio.NewReader(r).ReadLine()

  if err != nil {

    errCh <- err

  } else {

    ch <- string(line)

  }

  cmd.Wait() // <-- add this line

}()

这将导致 goroutine 阻塞,而这正是您试图避免的。另一种方法是应用程序为每个命令泄漏资源。


查看完整回答
反对 回复 2021-11-08
  • 1 回答
  • 0 关注
  • 155 浏览
慕课专栏
更多

添加回答

举报

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