我在 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 个对象时引发的ObjectSpace
。sleep
此外,手动垃圾收集无法改善任何这些计数,通过插入调用减慢我的脚本也是如此。
因此,我的问题是:
我是否从根本上误解了操作系统限制的性质——它是否涵盖了进程的整个生命周期?如果是这样,Web服务器如何避免在访问ulimit -n
文件后崩溃?ruby 是在其对象系统之外保留其文件句柄,还是内核在计算“并发”访问时非常慢?
编辑 20130417:
strace
表示 ruby 不会将其所有数据写入文件,在这样做之前返回并释放互斥锁。因此,文件处理堆栈直到操作系统限制。
为了解决这个问题,我使用了syswrite
/ sysread
,同步模式,并flush
在之前调用了close
。这些方法都不起作用。
因此,我的问题被修改为: 为什么 ruby 无法关闭其文件句柄,我该如何强制它这样做?