我正在尝试使用Ruby的Process.fork
来完成某些事情。但是,在几秒钟之后它会引发以下异常:fork: Resource temporarily unavailable - fork(2) (Errno::EAGAIN)
根据我的理解,经过一些研究后,操作系统对操作系统上允许运行的进程数量有限制。上面的错误表明我读到的限制超出了限制。
然而我不明白的是,在重新循环相同的代码之前,我在最后明确Process.wait
以便所有子进程完成时如何超出此限制。前10个左右的循环可以正常工作,但之后fork: Resource temporarily unavailable - fork(2) (Errno::EAGAIN)
再次出现。
以下是我正在做的一个简单示例:
loop do
records = MyDatabase.find_batch_of_25_records_to_process_concurrently
records.each do |record|
Process.fork do # Spawn 25 child processes, one for each record
record.process!
end
end
Process.wait # wait until 25 Child Processes are finished/killed (, right?)
sleep 5
end
所以会发生什么,我从我的数据库中获取25条记录,然后我想同时处理它们。所以我遍历每个记录,并为每个记录分叉一个进程。它最终会将主要进程分叉25次。然后我调用Process.wait
,这样它就不会重新循环,直到所有子进程完成。然后它会睡5秒并重复这个过程,重新分配25个新的子进程等等。
有没有人知道为什么在几次循环之后,这个错误(fork: Resource temporarily unavailable - fork(2) (Errno::EAGAIN)
)被提出了?希望如何防止它发生?看看我的ActivityMonitor,我看到25个新的Ruby进程正在生成。然后在2秒左右之后,他们再次消失,因为他们完成了任务。然后,活动监视器中出现25个新进程,然后再次消失。所以我假设它们实际上正在产生并被杀死,但仍然会出现错误。
非常感谢任何反馈,谢谢!
答案 0 :(得分:1)
事实证明Process.wait
是导致此问题的原因。我认为它可能无法正确地将子进程注册为“已完成”。
我最终做的是以下内容:
loop do
pids = Array.new # Create a local variable to hold an array of pids
records = MyDatabase.find_batch_of_25_records_to_process_concurrently
records.each do |record|
pids << Process.fork do # Fork a child, and add it's returned pid to the array
record.process!
end
end
pids.each do |pid|
Process.wait(pid) # Explicitly wait for **each** pid individually
end
sleep 5
end
这似乎工作正常,它不再崩溃10秒。我将暂时停止运行一段时间,看看它是否最终会崩溃。在任何情况下,到目前为止看起来fork: Resource temporarily unavailable - fork(2) (Errno::EAGAIN)
错误不再是基于这种方式提出的。
答案 1 :(得分:1)
不简单Process.waitall
?