猿问

当非阻塞 readline 挂起时泄漏 goroutine

假设你有这样的结构:


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 "", err

case line := <-ch:

    return line, nil

case <-time.After(5 * time.Second):

    return "", TimeoutError

}

在 5 秒超时的情况下,goroutine 会挂起,直到 ReadLine 返回,这可能永远不会发生。我的项目是一个长期运行的服务器,所以我不想要卡住的 goroutines 的积累。


千万里不及你
浏览 156回答 1
1回答

Smart猫小萌

ReadLine 在进程退出或方法读取一行之前不会返回。管道没有截止日期或超时机制。如果对 ReadLine 的调用在超时后返回,goroutine 将阻塞。这可以通过使用缓冲通道来解决:ch := make(chan string, 1)errCh := make(chan error, 1)应用程序应该调用Wait来清理与命令关联的资源。goroutine 是调用它的好地方:go func() {&nbsp; line, _, err := bufio.NewReader(r).ReadLine()&nbsp; if err != nil {&nbsp; &nbsp; errCh <- err&nbsp; } else {&nbsp; &nbsp; ch <- string(line)&nbsp; }&nbsp; cmd.Wait() // <-- add this line}()这将导致 goroutine 阻塞,而这正是您试图避免的。另一种方法是应用程序为每个命令泄漏资源。
随时随地看视频慕课网APP

相关分类

Go
我要回答