Ruby 来自 child 的标准输出的管道不是 closing/how 来检测空管道
Ruby pipe from child's stdout not closing/how to detect empty pipe
我有一个包含任意数据的文件 testin
。我分叉,将 stdout
连接到 parent 的管道,然后执行 dd
以读取文件并将其推入管道。然后另外两个 children 与来自 parent 的管道中的 stdin
类似地执行。 parent 然后从第一个进程读取字节并将它们写入另外两个 children.
我的问题是 until 循环永远不会结束。如果我将 #closed?
作为条件从第一个进程发送到管道,它会卡在下一个 #read
等待进程完成后的更多数据。如果我发送 #eof?
它会卡在 #eof?
.
为什么我没有收到 EOF 或者为什么管道没有关闭?我应该如何检测没有更多数据?
pipe1r, pipe1w = IO.pipe
pid1 = fork do
$stdout.reopen(pipe1w)
exec 'dd', 'if=testin'
end
pipe2r, pipe2w = IO.pipe
pid2 = fork do
$stdin.reopen(pipe2r)
exec 'dd', 'of=testout1'
end
pipe3r, pipe3w = IO.pipe
pid3 = fork do
$stdin.reopen(pipe3r)
exec 'dd', 'of=testout2'
end
until pipe1r.closed?
byte = pipe1r.read(1)
pipe2w.write(byte)
pipe3w.write(byte)
end
pipe2w.close
pipe3w.close
pid, status = Process.wait2(pid1)
puts 'Process 1 was a ' + (status.success? ? 'success' : 'failure')
pid, status = Process.wait2(pid2)
puts 'Process 2 was a ' + (status.success? ? 'success' : 'failure')
pid, status = Process.wait2(pid3)
puts 'Process 3 was a ' + (status.success? ? 'success' : 'failure')
已解决: 根据 matthewd 的回答,pipe1w.close
在分叉第一个进程并使用 until pipe1r.eof?
作为循环条件修复它后——接收到 EOF 并且循环结束。
您还没有在父进程中关闭pipe1w
。
你的循环之前需要一个pipe1w.close
,否则管道永远不会为空:分叉进程已经停止写入(并关闭它的副本),但父进程仍然可以写入它。
我有一个包含任意数据的文件 testin
。我分叉,将 stdout
连接到 parent 的管道,然后执行 dd
以读取文件并将其推入管道。然后另外两个 children 与来自 parent 的管道中的 stdin
类似地执行。 parent 然后从第一个进程读取字节并将它们写入另外两个 children.
我的问题是 until 循环永远不会结束。如果我将 #closed?
作为条件从第一个进程发送到管道,它会卡在下一个 #read
等待进程完成后的更多数据。如果我发送 #eof?
它会卡在 #eof?
.
为什么我没有收到 EOF 或者为什么管道没有关闭?我应该如何检测没有更多数据?
pipe1r, pipe1w = IO.pipe
pid1 = fork do
$stdout.reopen(pipe1w)
exec 'dd', 'if=testin'
end
pipe2r, pipe2w = IO.pipe
pid2 = fork do
$stdin.reopen(pipe2r)
exec 'dd', 'of=testout1'
end
pipe3r, pipe3w = IO.pipe
pid3 = fork do
$stdin.reopen(pipe3r)
exec 'dd', 'of=testout2'
end
until pipe1r.closed?
byte = pipe1r.read(1)
pipe2w.write(byte)
pipe3w.write(byte)
end
pipe2w.close
pipe3w.close
pid, status = Process.wait2(pid1)
puts 'Process 1 was a ' + (status.success? ? 'success' : 'failure')
pid, status = Process.wait2(pid2)
puts 'Process 2 was a ' + (status.success? ? 'success' : 'failure')
pid, status = Process.wait2(pid3)
puts 'Process 3 was a ' + (status.success? ? 'success' : 'failure')
已解决: 根据 matthewd 的回答,pipe1w.close
在分叉第一个进程并使用 until pipe1r.eof?
作为循环条件修复它后——接收到 EOF 并且循环结束。
您还没有在父进程中关闭pipe1w
。
你的循环之前需要一个pipe1w.close
,否则管道永远不会为空:分叉进程已经停止写入(并关闭它的副本),但父进程仍然可以写入它。