问题内容 我花了几个小时尝试理解底层逻辑,但没有任何进展。下面的代码在第一次迭代后返回死锁。如果我在 io.copy 之前关闭 writer,死锁就会消失,但不会打印任何内容(因为管道
我花了几个小时尝试理解底层逻辑,但没有任何进展。下面的代码在第一次迭代后返回死锁。如果我在 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,并永远挂起。
代码的另一个问题是您尝试多次关闭管道(每次循环代码重复时)。一般情况下,close
able 对象只应关闭一次,并且在 close
d 后被假定为不可用。如果您需要重新使用它们,您应该创建一个新实例。
这是代码的工作修订版:
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)
}
}
以上就是尝试写入/读取时 io.Pipe 和死锁的详细内容,更多请关注编程网其它相关文章!
--结束END--
本文标题: 尝试写入/读取时 io.Pipe 和死锁
本文链接: https://lsjlt.com/news/561385.html(转载时请注明来源链接)
有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341
2024-05-24
2024-05-24
2024-05-24
2024-05-24
2024-05-24
2024-05-24
2024-05-24
2024-05-24
2024-05-24
2024-05-24
回答
回答
回答
回答
回答
回答
回答
回答
回答
回答
0