1

我有以下代码:

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)
4

1 回答 1

0

如果子节点的输出大于管道容量,则子节点可能会阻止将管道写入父节点。理想情况下,父级将在子管道上执行选择循环或生成从子管道读取的线程,以便在数据可用时消耗数据,以防止子管道在满管道上停滞和失败。在实践中,如果子输出很小,只需执行waitalland read 即可。

其他人已经以可重用的方式解决了这些问题,您可以尝试并行 gem以避免编写一堆不必要的代码。

于 2013-01-21T00:41:29.240 回答