You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用io.Pipe时Goroutine中io.Copy死锁问题及解决问询

问题原因

使用io.Pipe时,PipeReader的Read操作会一直阻塞,直到对应的PipeWriter被关闭或有新数据写入。原代码中,io.Copy(pipeWriter, read)完成后未关闭pipeWriter,导致goroutine内的io.Copy(os.Stdout, pipeReader)持续等待更多数据;而main goroutine卡在wg.Wait()无法推进,最终所有goroutine进入休眠状态,触发死锁。

解决方案

在完成PipeWriter的数据写入后,必须关闭PipeWriter,以此通知PipeReader数据传输结束,让io.Copy正常返回。推荐用defer确保无论写入操作成功与否,PipeWriter都会被关闭。

修改后的代码:

func main() {
    read := strings.NewReader("abcdefghij")
    pipeReader, pipeWriter := io.Pipe()

    var wg sync.WaitGroup
    wg.Add(1)
    go func() {
        defer wg.Done()
        println("Start copy")
        _, err := io.Copy(os.Stdout, pipeReader)
        if err != nil {
            println(err.Error())
        }
        println("End copy")
    }()

    defer pipeWriter.Close()
    _, err := io.Copy(pipeWriter, read)
    if err != nil {
        println(err.Error())
    }

    wg.Wait()
}

关键修改点

  • defer pipeWriter.Close():保证PipeWriter最终被关闭,无论io.Copy是否出错,都能终止PipeReader的阻塞等待。
  • 将wg.Done()放入defer:确保goroutine即使在io.Copy出错时,也能正确标记任务完成,避免wg.Wait()永久阻塞。

扩展场景说明

如果实际代码中使用io.MultiWriter连接多个PipeWriter,需要为每个PipeWriter单独执行关闭操作,确保对应的PipeReader都能收到结束信号,避免类似死锁问题。

内容的提问来源于stack exchange,提问作者EtTuBrute

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 02:50:52