我有以下代码:
data_set = [1,2,3,4,5,6]
results = []
data_set.each do |ds|
puts "Before fork #{ds}"
r,w = IO.pipe
if pid = Process.fork
w.close
child_result = r.read
results << child_result
else
puts "Child worker for #{ds}"
sleep(ds * 5)
r.close
w.write(ds * 2)
exit
end
end
Process.waitall
puts "Ended everything #{results}"
基本上,我希望每个孩子都做一些工作,然后将结果传递给父母。我的代码现在并不是并行运行,我不知道我的问题到底在哪里,可能是因为我在父母那里读书,但我不确定。我需要做什么才能让它运行异步?
编辑:我将代码更改为此,似乎工作正常。我有没有看到任何问题?data_set = [1,2,3,4,5,6]
child_pipes = []
results = []
data_set.each do |ds|
puts "Before fork #{ds}"
r,w = IO.pipe
if pid = Process.fork
w.close
child_pipes << r
else
puts "Child worker for #{ds}"
sleep(ds * 5)
r.close
w.write(ds * 2)
exit
end
end
Process.waitall
puts child_pipes.map(&:read)
答案 0 :(得分:0)
如果孩子的输出大于管道容量,则孩子可能block writing to the pipe到父母。{}理想情况下,父节点将在子管道上执行选择循环,或者从子管道中生成读取线程,以便在可用时使用数据,以防止子节点在完整管道上停顿并失败。实际上,如果子输出很小,只需执行waitall
和读取即可。
其他人已经以可重用的方式解决了这些问题,您可以尝试使用parallel gem来避免编写一堆不必要的代码。