2017-08-28 158 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,也許(幾乎可以肯定)它有一次只啓動一些異步任務的功能,所以你也可以這樣做。