0

0

尝试写入/读取时 io.Pipe 和死锁

王林

王林

发布时间:2024-02-06 09:40:03

|

1343人浏览过

|

来源于stackoverflow

转载

尝试写入/读取时 io.pipe 和死锁

问题内容

我花了几个小时尝试理解底层逻辑,但没有任何进展。下面的代码在第一次迭代后返回死锁。如果我在 io.copy 之前关闭 writer,死锁就会消失,但不会打印任何内容(因为管道写入端在读取之前已关闭)

func main() {
    reader, writer := io.pipe()
    c := make(chan string)

    go func() {
        for i := 0; i < 5; i++ {
            text := fmt.sprintf("hello %vth time", i+1)
            c <- text
        }

        close(c)
    }()

    for msg := range c {
        msg = fmt.sprintf("\nreceived from channel -> %v\n", msg)

        go fmt.fprint(writer, msg)
        io.copy(os.stdout, reader)
        writer.close()
    }

}

这是运行代码后的错误

received from channel -> hello 1th time fatal error: all goroutines
are asleep - deadlock!
goroutine 1 [select]: io.(*pipe).read(0xc000130120, {0xc00013e000,
0x8000, 0xc00011e001?})
/usr/lib/go/src/io/pipe.go:57 +0xb1 io.(*PipeReader).Read(0x0?, {0xc00013e000?, 0xc00011e050?, 0x10?})
/usr/lib/go/src/io/pipe.go:136 +0x25 io.copyBuffer({0x4bde98, 0xc00011e050}, {0x4bddb8, 0xc00012e018}, {0x0, 0x0, 0x0})
/usr/lib/go/src/io/io.go:427 +0x1b2 io.Copy(...)
/usr/lib/go/src/io/io.go:386 os.genericReadFrom(0x101c00002c500?, {0x4bddb8, 0xc00012e018})
/usr/lib/go/src/os/file.go:161 +0x67 os.(*File).ReadFrom(0xc00012e008, {0x4bddb8, 0xc00012e018})
/usr/lib/go/src/os/file.go:155 +0x1b0 io.copyBuffer({0x4bde38, 0xc00012e008}, {0x4bddb8, 0xc00012e018}, {0x0, 0x0, 0x0})
/usr/lib/go/src/io/io.go:413 +0x14b io.Copy(...)
/usr/lib/go/src/io/io.go:386 main.pipetest()
/home/stranger/source-code/golang/ipctest/pipes/main.go:39 +0x1ae main.main()
/home/stranger/source-code/golang/ipctest/pipes/main.go:10 +0x17
goroutine 18 [chan send]: main.pipetest.func1()
/home/stranger/source-code/golang/ipctest/pipes/main.go:29 +0x85 created by main.pipetest
/home/stranger/source-code/golang/ipctest/pipes/main.go:26 +0x17a exit status 2

正确答案


io.copy 不断尝试复制,直到读取器到达 eof(在本例中,当管道关闭时)。由于您在 io.copy 结束后调用 writer.close() after ,因此 io.copy 将永远不会看到 eof,并永远挂起。

SEO GPT
SEO GPT

免费的白帽SEO,PPC和网站经销商平台

下载

代码的另一个问题是您尝试多次关闭管道(每次循环代码重复时)。一般情况下,closeable 对象只应关闭一次,并且在 closed 后被假定为不可用。如果您需要重新使用它们,您应该创建一个新实例。

这是代码的工作修订版:

func main() {
    c := make(chan string)

    go func() {
        for i := 0; i < 5; i++ {
            text := fmt.Sprintf("hello %vth time", i+1)
            c <- text
        }

        close(c)
    }()

    for msg := range c {
        msg = fmt.Sprintf("\nreceived from channel -> %v\n", msg)

        // Create a new pipe for this message.
        reader, writer := io.Pipe()
        go func() {
            fmt.Fprint(writer, msg)
            // Close the pipe after writing the message.
            writer.Close()
        }()

        io.Copy(os.Stdout, reader)
    }
}

相关标签:

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
Java 项目构建与依赖管理(Maven / Gradle)
Java 项目构建与依赖管理(Maven / Gradle)

本专题系统讲解 Java 项目构建与依赖管理的完整体系,重点覆盖 Maven 与 Gradle 的核心概念、项目生命周期、依赖冲突解决、多模块项目管理、构建加速与版本发布规范。通过真实项目结构示例,帮助学习者掌握 从零搭建、维护到发布 Java 工程的标准化流程,提升在实际团队开发中的工程能力与协作效率。

11

2026.01.12

c++主流开发框架汇总
c++主流开发框架汇总

本专题整合了c++开发框架推荐,阅读专题下面的文章了解更多详细内容。

106

2026.01.09

c++框架学习教程汇总
c++框架学习教程汇总

本专题整合了c++框架学习教程汇总,阅读专题下面的文章了解更多详细内容。

64

2026.01.09

学python好用的网站推荐
学python好用的网站推荐

本专题整合了python学习教程汇总,阅读专题下面的文章了解更多详细内容。

139

2026.01.09

学python网站汇总
学python网站汇总

本专题整合了学python网站汇总,阅读专题下面的文章了解更多详细内容。

13

2026.01.09

python学习网站
python学习网站

本专题整合了python学习相关推荐汇总,阅读专题下面的文章了解更多详细内容。

19

2026.01.09

俄罗斯手机浏览器地址汇总
俄罗斯手机浏览器地址汇总

汇总俄罗斯Yandex手机浏览器官方网址入口,涵盖国际版与俄语版,适配移动端访问,一键直达搜索、地图、新闻等核心服务。

93

2026.01.09

漫蛙稳定版地址大全
漫蛙稳定版地址大全

漫蛙稳定版地址大全汇总最新可用入口,包含漫蛙manwa漫画防走失官网链接,确保用户随时畅读海量正版漫画资源,建议收藏备用,避免因域名变动无法访问。

480

2026.01.09

php学习网站大全
php学习网站大全

精选多个优质PHP入门学习网站,涵盖教程、实战与文档,适合零基础到进阶开发者,助你高效掌握PHP编程。

52

2026.01.09

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号