2017-08-28 39 views
0

我已经编写了一个递归读取一个目录中的文件,修改它们并将它们写入另一个目录的程序。每次我运行该程序时,都会在几百次迭代后出现恶意程序。我再次运行它,似乎完成了这项任务。nodejs/Mac并打开文件限制

无论是nodejs还是Mac OS X,或者很可能是nodejs-on-Mac-OS-X,似乎都对可同时打开的文件数量有限制。到处搜索,我发现解决方案是使用像ulimit -n 10480这样的东西,一切都会好的。这是正确的方式吗?本能地,我宁愿不修补我的系统设置,而是修改我的程序以在极限内工作。

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

回答

1

您可以使用带有限制命令的异步库将处理文件的数量限制为特定数量。例如:

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

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

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

是,MacOS的(也可能是每一个UNIX变体),对打开的文件数量的限制,是的,Perl中没有为你提到的原因这个问题。

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

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

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

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