質問
私が行う場合は、
Process.fork do
x
end
どのように私は(例えば、真/ FASE /文字列)が返さxは何を知ることができますか?
(ファイル/データベースへの書き込みは、オプションではありません...)
解決 3
私はルビーに(ユーザーのようないくつかの他の問題は、+配管・バッファを出た)、私は道に沿って検出されたすべてのソリューションを包んパラレル宝石に。
:今では同じように簡単ですresults = Parallel.map([1,2,3],:in_processes=>4) do |i|
execute_something(i)
end
または
results = Parallel.map([1,2,3],:in_threads=>4) do |i|
execute_something(i)
end
他のヒント
私たちは、実際には<のhref =「http://github.com/rails/rails/blob/eea7b5db1db5d7e6020c5bcb6b4d85afcbc2e696/activesupport/lib/active_support/testing/isolation.rb#L37-54」のrelでこの問題に対処しなければなりませんでした= "noreferrer">レール分離試験する。私は私のブログの上でそれについていくつかのを計上しました。
は、基本的には、何がやりたいことは、親と子でパイプ開いており、子供がパイプに書き込みを持っています。ここでは、子プロセスでブロックの内容を実行し、結果を取り戻すための簡単な方法があります:
def do_in_child
read, write = IO.pipe
pid = fork do
read.close
result = yield
Marshal.dump(result, write)
exit!(0) # skips exit handlers.
end
write.close
result = read.read
Process.wait(pid)
raise "child failed" if result.empty?
Marshal.load(result)
end
次に、あなたが実行できます:
do_in_child do
require "some_polluting_library"
SomePollutingLibrary.some_operation
end
あなたは子供に必要ならば、あなたは親にそのライブラリへのアクセス権を持っていないので、この方法を使用して、その型のオブジェクトを返すことができないことに注意してください。ただし、両方で利用できる任意の型を返すことができます。
また、あなたはこのたくさん使うので、もしここでは詳細の多くは(read.close
、Process.wait2(pid)
は)あなたはおそらく、あなたが再利用できるユーティリティライブラリにこれを移動する必要があり、主にハウスキーピングの詳細であることに注意します。
最後に、彼らはフォークをサポートしていないので、これは、WindowsまたはJRubyの上では動作しませんのでご注意ます。
すべての答えのおかげで、私は私の解決策を持って実行している、まだ非フォーク環境をどのように処理するかを確認する必要がありますが、今のところ、それは動作します)。
read, write = IO.pipe
Process.fork do
write.puts "test"
end
Process.fork do
write.puts 'test 2'
end
Process.wait
Process.wait
write.close
puts read.read
read.close
あなたはアクションでそれを見ることができます@ parallel_specsのRailsプラグインする
はい、あなたは内部のブロックを実行するためのサブプロセスを作成することができます。
私はお勧め aw
宝石するます:
Aw.fork! { 6 * 7 } # => 42
もちろん、それは副作用から防ぎます:
arr = ['foo']
Aw.fork! { arr << 'FUU' } # => ["foo", "FUU"]
arr # => ["foo"]
のドキュメントによると:
ブロックが指定されている場合は、、そのブロックがサブプロセスで実行され、サブプロセスはゼロのステータスで終了します。
は、あなたがブロックとそれを呼び出すのであれば、それは基本的にUnixでfork()
システムコール(親は、子供がnil
を受けた新しいプロセスのPIDを受ける)と同じように機能し、それ以外の場合は0を返します。
2つのUNIXプロセス間のフォークの通信は、主に戻りコードとすぎ。ただし、2つのプロセス間のファイル記述子を開き、このファイル記述子を介してプロセス間でデータを渡すことができます。これは、通常のUnixのパイプの方法です。
。 あなたはMarshal.dump()とMarshal.loadを()の値渡したい場合、あなたは簡単にそれらのRubyプロセス間でRubyのオブジェクトを渡すことができます。
これを行うには、共有メモリを使用することができます。次のようなものは動作します:
str = 'from parent'
Thread.new do
str = 'from child'
end
sleep(1)
puts str # outputs "from child"
同時実行とはいえ、かなりトリッキーなことができ、そしてこの方法は、理由の大きな部分を占めている共有メモリにアクセスする - あなたは、変数や他のプロセスを持っているすべての時間があなたの下からそれを変えるかもしれない、あなたは非常に警戒する必要があります。また、あなたはもっと面倒が、最も些細なコードが、いずれについても、おそらくより安全であるパイプを、使用することができ、また、任意のコマンドを実行するために使用することができます。ここではストレートIO.popenためRDOCのうちの、一例です。
f = IO.popen("uname")
p f.readlines # outputs "Darwin", at least on my box :-)