nodejs / Mac和打开文件限制

时间:2017-08-28 01:18:38

标签: node.js

我编写了一个程序,以递归方式读取一个目录中的文件,修改它们并将它们写入另一个目录。每次我运行该程序时,它会在经过几百次迭代后发生错误。我只是再次运行它,它似乎完成了任务。

nodejs或Mac OS X,或者很可能是Mac-OS-X上的nodejs,似乎对可以一次打开的文件数量有某种限制。搜索周围,我发现解决方案是使用类似ulimit -n 10480的东西,一切都会好的。这是正确的方法吗?本能地,我宁愿不修改我的系统设置,而是修改我的程序以在限制范围内工作。

观察:早些时候我曾经使用Perl来完成我上面描述的任务,我从来没有遇到过任何问题。我假设这是因为我打开,转换,然后关闭文件,然后继续前进。在nodejs中,使用async模式,我无法在进入下一个文件之前关闭文件。如果我在sync模式下执行任务,则可以正常工作。

2 个答案:

答案 0 :(得分:1)

您可以将async库与limit命令一起使用,以将处理的文件数限制为特定数量。例如:

async.eachLimit(files, 1000, function (file, next) {
    processFile(file, next);
}, done);

如果您希望在转到下一个文件之前处理单个文件,只需使用eachSeries。

async.eachSeries(files, function (file, next) {
    processFile(file, next);
}, done);

答案 1 :(得分:1)

是的,macOS(可能还有每个UNIX变体)对打开文件的数量有限制,是的,Perl没有你提到的那个问题。

ulimit不是一个设置你似乎想到它的方式的系统。 ulimit适用于当前进程,并在启动时复制到其子进程,这意味着如果在进程中提高限制,则不会影响其他进程,如果您是改变某些全局约束资源(如物理内存使用)的限制,可能会使其他程序挨饿。换句话说,如果在shell中运行ulimit -n 10480,效果只会持续到退出该shell。

在macOS上,系统范围的打开文件的实际上限由命令sysctl kern.maxfiles给出。无论ulimit设置如何,如果您尝试一次打开整个系统上的文件,打开文件将失败。在我的系统上,它是12288.这是“系统设置”,修补可以产生更持久的效果:提高它会增加内核所需的静态内存量(按我不知道的数量),降低它可能会使进程从文件描述符。

如果您的脚本相对较短,则使用ulimit提高文件描述符限制可能不是问题。

虽然我不知道node.js,也许(几乎可以肯定)它一次只能启动一些异步任务,所以你也可以这样做。