我在函数中有以下代码:
num_procs.times do
pid = fork
unless pid
DRb.start_service
ts = Rinda::TupleSpaceProxy.new(DRbObject.new_with_uri('druby://localhost:53421'))
loop do
item = ts.take([:enum, nil, nil])
# our termination tuple
break if item == [:enum, -1, nil]
result =
begin
block.call(item[2])
rescue Object => e
e
end
# return result
ts.write([:result, item[1], result])
end
DRb.stop_service
exit!
end
pids << pid
end
pts = Rinda::TupleSpace.new
# write termination tuples
items.size.times do
pts.write([:enum, -1, nil])
end
items.each_with_index { |item, index|
pts.write([:enum, index, item])
}
DRb.start_service('druby://localhost:53421', pts)
# Grab results
items.size.times do
result_tuples << pts.take([:result, nil, nil])
end
pp "Waiting for pids: #{pids.inspect}" if FORKIFY_DEBUG
pids.each { |p| Process.waitpid(p) }
DRb.stop_service
# gather results and sort them
result_tuples.map { |t|
results[t[1]] = t[2]
}
return results
这段代码分叉了很多次,然后孩子们尝试使用Rinda :: TupleSpaceProxy而不是DRb从父级获取元组。父项为每个进程推送项目以调用块。然后,孩子们将不同元组的结果返回给父级,父级将它们聚合在一起。
此代码位于库中,因此我不希望用户必须启动类似beanstalkd或类似的东西才能为进程池排队作业。我的问题是:
我是否有更好的方法可以进行跨进程队列通信?
答案 0 :(得分:0)
(我尝试运行上面的代码,但即使经过一些调整和要求,我也无法实现它,所以请不要赘述这个建议。)
而不是DRb,最好选择beanstalk / delayed_job / [other queue]依赖关系。如果这只是一个后台工作,我建议dj,因为它是众所周知的并且易于入手(参见this example快速入门)。如果您可以发布更多代码,那么它会更容易帮助。