题
如果我
Process.fork do
x
end
我怎么能知道什么是X返回(例如真/ FASE /串)?
(写入文件/数据库不是一个选项...)
解决方案 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
其他提示
我们其实刚刚处理中的滑轨隔离测试。我张贴了关于它在我的博客一些。
基本上,你想要做的是开放的家长和孩子的管道,并有孩子写到管道。这里有一个简单的方法来运行一个块的内容在一个子进程,并取回结果:
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"]
根据该文件:
如果指定的块,该块被在子进程运行,并且子过程具有零状态终止。
因此,如果您与块调用它,则返回0,否则,它的功能基本上与在Unix的fork()
系统调用(父接收新进程的PID,子接收nil
)。
两台Unix过程之间的叉通信主要返回代码,仅此而已。但是,可以打开两个过程之间的文件描述符和越过该文件描述符的过程之间的数据:这是在正常的Unix管方式
如果您会通过Marshal.dump()和Marshal.load()的值,则能够轻易地通过那些红宝石进程之间Ruby对象。
您可以使用共享内存这样做,如果孩子只是需要Ruby代码的一小块。像下面的东西将工作:
str = 'from parent'
Thread.new do
str = 'from child'
end
sleep(1)
puts str # outputs "from child"
并发性可能会非常棘手,虽然和访问共享内存这种方式的很大一部分原因 - 你已经有了一个变量,另一个进程可能会出从下你改变它任何时候,你应该非常谨慎。或者,你可以使用一个管道,这是比较麻烦的,但可能对于任何但是最琐碎的代码更安全,也可用于运行任意命令。下面是一个例子,直出的RDoc为IO.popen的:
f = IO.popen("uname")
p f.readlines # outputs "Darwin", at least on my box :-)