goroutine泄漏是否会发生在具有一个缓冲区的通道中,该缓冲区有两个输入但只有一个输出?

时间:2017-12-04 04:05:30

标签: go

我有一个用于在两个io.ReadWriter之间转发消息的函数。一旦发生错误,我需要记录错误并返回。但我想我的代码中可能存在goroutine泄漏问题:

func transport(rw1, rw2 io.ReadWriter) error {
    errc := make(chan error, 1) // only one buffer
    go func() {
        _, err := io.Copy(rw1, rw2)
        errc <- err
    }()

    go func() {
        _, err := io.Copy(rw2, rw1)
        errc <- err
    }()

    err := <-errc // only one error catched
    if err != nil && err == io.EOF {
        err = nil
    }
    return err
}

因为在这个函数中只能捕获一个错误,第二个goroutine会退出并正常使用吗?或者我应该再写一次err <- errc来接收另一个错误。

1 个答案:

答案 0 :(得分:3)

接收来自一个goroutine的值,另一个被缓冲。两个goroutine都可以发送到频道并退出。没有泄漏。

您可能希望同时接收这两个值,以确保应用程序在第一个goroutine发送成功并且第二个goroutine遇到错误时检测到错误。

var err error
for i := 0; i < 2; i++ {
  if e := <-errc; e != nil {
    err = e
  }
}

因为io.Copy没有返回io.EOF,所以在收集错误时无需检查io.EOF。

代码可以简化为使用单个goroutine:

errc := make(chan error, 1)
go func() {
    _, err := io.Copy(rw1, rw2)
    errc <- err
}()

_, err := io.Copy(rw2, rw1)

if e := <-errc; e != nil {
   err = e
}