Yeh*_*atz 31
我们实际上只需要在Rails隔离测试中处理这个问题.我在博客上发布了一些相关信息.
基本上,您要做的是在父级和子级中打开管道,并让子级写入管道.这是在子进程中运行块的内容并获取结果的简单方法:
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
Run Code Online (Sandbox Code Playgroud)
然后你可以运行:
do_in_child do
require "some_polluting_library"
SomePollutingLibrary.some_operation
end
Run Code Online (Sandbox Code Playgroud)
请注意,如果在子级中执行require,则无法访问父级中的该库,因此无法使用此方法返回该类型的对象.但是,您可以返回两者中可用的任何类型.
还要注意的是这里很多(详细read.close,Process.wait2(pid))大都是看家的细节,所以如果你使用这个有很多你应该移到了这一点,到公共图书馆,你可以重复使用.
最后请注意,这不适用于Windows或JRuby,因为它们不支持分叉.
gro*_*ser 11
感谢所有的答案,我启动并运行了我的解决方案,仍然需要看看如何处理非分叉环境,但现在它的工作:)
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
Run Code Online (Sandbox Code Playgroud)
你可以在@ parallel_specs Rails插件中看到它
gro*_*ser 10
我将沿途发现的所有解决方案(用户退出+管道缓冲区等其他问题)包装到ruby parallel gem中.现在它很简单:
results = Parallel.map([1,2,3],:in_processes=>4) do |i|
execute_something(i)
end
Run Code Online (Sandbox Code Playgroud)
要么
results = Parallel.map([1,2,3],:in_threads=>4) do |i|
execute_something(i)
end
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
10154 次 |
| 最近记录: |