我有一个用于在两个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
来接收另一个错误。
答案 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
}