簡體   English   中英

node.js是否在主線程中運行異步文件讀/寫?

[英]Does node.js run asynchronous file reading/writing in main thread?

我原以為讀取文件等異步處理在其他線程上處理,在其他線程讀完時通知主線程。

我試過跟隨。

const fs = require("fs")

console.time(1)
fs.readFile("largefile", x => console.timeEnd(1))

這顯示1500ms

其次我試着跟隨。

const fs = require("fs")

console.time(1)
fs.readFile("largefile", x => console.timeEnd(1))

// block main thread 1sec
const s = Date.now()
while(Date.now() - s < 1000);

如果在其他線程上處理異步進程,它將顯示1500ms 但是,我得到了2500ms

我嘗試了另一個。

const fs = require("fs")

console.time(1)
fs.readFile("largefile", x => console.timeEnd(1))

setInterval(() => {
    const s = Date.now()
    while(Date.now() - s < 100);
}, 100)

我等了幾分鍾,但沒有消息。

nodejs是否在主線程上處理繁重的處理?

當我需要讀取和寫入太多大文件時,我應該使用child_process嗎?

I / O是在封面下使用非阻塞操作完成的(而不是占用主線程); 但是,I / O 完成 (例如,回調)是在啟動I / O操作的線程上完成的(在您的示例中,一個主要的JavaScript線程,因為您沒有使用worker )。 如果你使該線程飽和,它就沒有機會處理回調。

你的例子中的主要問題是

  1. 您正在使用便捷函數readFile將大文件一次性讀入內存。

  2. 您的測試是合成的,執行極其耗費CPU的事情,不太可能模擬您的實際應用程序的特征。

nodejs是否在主線程上處理繁重的處理?

諸如readFile之類的便利函數的某些部分是在你調用它的線程(你的例子中的主線程)上實現的,是的。 readFile是使用fs.read在JavaScript中fs.read ,並且在處理完前一個塊之后才會請求下一個數據塊。 塊的默認大小(截至本文時)為8k(8,192)字節。

你可以在源代碼中看到這個:

這意味着如果主線程被阻塞(你的第二個代碼塊)或負載極重(你的第三個代碼塊),那么處理每8k一次的read回調非常慢,這會極大地影響便利功能的性能:

  • 你的第二個代碼塊(1,000ms忙等待)阻止了對前8k數據的第一次回調的處理,因此它阻止了整個1,000ms的讀取過程,在此過程中它被阻塞。
  • 你的第三個代碼塊( setInterval調用忙等待100ms每100ms)與readFile的實現合謀,在從文件讀取的每個8k塊之間引入~100ms的延遲。 任何大小的文件都需要長時間才能以~820字節/秒的速度讀取。

但是,你的測試再次是合成的。 即使是一次100毫秒阻塞主線程也是不尋常的。

當我需要讀取和寫入太多大文件時,我應該使用child_process嗎?

不能。只需使用基本I / O操作( readwrite )以合理大小的塊進行,而不是使用readFile等便捷功能。 使用子進程對於使用工作線程至少同樣糟糕,甚至更糟,Node.js開發團隊在工作線程文檔中有這樣的說法:

worker對於執行CPU密集型JavaScript操作很有用; 不要將它們用於I / O,因為Node.js用於異步執行操作的內置機制已經比工作線程更有效地處理它。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM