7

我在 ruby​​ (2.0.0 p39474) 中执行非常快速的文件访问,并不断收到异常Too many open files

看过这个线程这里和其他各种来源后,我很清楚操作系统的限制(1024在我的系统上设置)。

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

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

wherefilename会发生快速变化,具体取决于调用该部分的线程。据我了解,此表单在块后放弃其文件句柄。

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

File此外,异常本身是在仅报告 10-40 个对象时引发的ObjectSpacesleep此外,手动垃圾收集无法改善任何这些计数,通过插入调用减慢我的脚本也是如此。

因此,我的问题是:

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

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

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

因此,我的问题被修改为: 为什么 ruby​​ 无法关闭其文件句柄,我该如何强制它这样做?

4

1 回答 1

3

使用dtracestrace或系统上的任何等效项,并准确找出正在打开的文件。

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

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

于 2013-04-16T16:02:22.597 回答