Ruby文件句柄管理(打开文件太多)

时间:2013-04-16 15:53:08

标签: ruby file-io limits

我在ruby(2.0.0 p39474)中执行非常快速的文件访问,并继续获取异常Too many open files

查看了this threadhere以及其他各种来源后,我很清楚操作系统限制(在我的系统上设置为1024)。

执行此文件访问的代码部分是互斥的,采用以下形式:

File.open( filename, 'w'){|f| Marshal.dump(value, f) }

其中filename会发生快速变化,具体取决于调用该部分的线程。我的理解是这个表单在块之后放弃了它的文件句柄。

我可以使用ObjectSpace.each_object(File)验证打开的File个对象的数量。这报告内存中最多有100个驻留,但只有一个是开放的,正如预期的那样。

此外,当File报告的对象只有10-40个ObjectSpace时,异常本身就会被抛出。此外,手动垃圾收集无法改善任何这些计数,因为通过插入sleep调用来减慢我的脚本速度。

我的问题是:

  • 我是否从根本上误解了操作系统限制的性质 - 它是否涵盖了流程的整个生命周期?
    • 如果是这样,在访问ulimit -n个文件后,Web服务器如何避免崩溃?
    • ruby​​是否在其对象系统之外保留其文件句柄,或者内核在计算“并发”访问权限时只是非常慢?

编辑20130417: strace表示ruby不会将所有数据写入文件,在执行此操作之前返回并释放互斥锁。因此,文件处理堆栈直到操作系统限制。

为了解决此问题,我使用了syswrite / sysread,同步模式,并在flush之前调用close。这些方法都不起作用。

我的问题因此修改为: 为什么ruby无法关闭其文件句柄,我该如何强制它执行此操作?

1 个答案:

答案 0 :(得分:3)

使用 dtrace strace 或系统中的任何等效文件,并准确找出正在打开的文件。

请注意,这些可能是套接字。

我同意您粘贴的代码似乎无法导致此问题,至少,并非没有相当奇怪的并发错误。