【问题标题】:Ruby's `Process.fork` and `Errno::EAGAIN` due to batch forking由于批量分叉,Ruby 的 `Process.fork` 和 `Errno::EAGAIN`
【发布时间】:2011-04-22 11:00:02
【问题描述】:

我正在尝试使用 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 个新进程出现在活动监视器中,然后又消失了。所以我假设它们实际上是被生成和杀死的,但仍然会引发错误。

非常感谢任何反馈,谢谢!

【问题讨论】:

    标签: ruby exception process fork


    【解决方案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) 错误似乎不再基于这种方式引发。

    【讨论】:

      【解决方案2】:

      是不是更简单Process.waitall

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-05-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-04-20
        • 1970-01-01
        • 1970-01-01
        • 2020-01-17
        相关资源
        最近更新 更多