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 を実行するだけで機能します。

再利用可能な方法でこれらの問題を解決した人もいます。不要なコードをたくさん書くのを避けるために、並列ジェムを試すことができます。

于 2013-01-21T00:41:29.240 に答える