blz*_*blz 5 javascript multithreading asynchronous node.js
我原以为读取文件等异步处理在其他线程上处理,在其他线程读完时通知主线程.
我试过跟随.
const fs = require("fs")
console.time(1)
fs.readFile("largefile", x => console.timeEnd(1))
Run Code Online (Sandbox Code Playgroud)
这表明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);
Run Code Online (Sandbox Code Playgroud)
它将显示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)
Run Code Online (Sandbox Code Playgroud)
我等了几分钟,但没有消息.
nodejs是否在主线程上处理繁重的处理?
child_process当我需要读取和写入太多大文件时,我应该使用吗?
I/O是在封面下使用非阻塞操作完成的(而不是占用主线程); 但是,I/O 完成(例如,回调)是在启动I/O操作的线程上完成的(在您的示例中,一个主要的JavaScript线程,因为您没有使用worker).如果你使该线程饱和,它就没有机会处理回调.
你的例子中的主要问题是
您正在使用便利功能,readFile一次性将大文件读入内存.
您的测试是合成的,执行极其耗费CPU的事情,不太可能模拟您的实际应用程序的特征.
nodejs是否在主线程上处理繁重的处理?
方便函数的某些部分readFile是在您调用它的线程(在您的示例中为主线程)上实现的,是的.readFile是使用JavaScript实现的fs.read,它在处理完前一个块之前不会请求下一个数据块; 块的默认大小(截至本文时)为8k(8,192)字节.
你可以在源代码中看到这个:
lib/fs.js,显示readFile使用ReadFileContext对象.internal/fs/read_file_context.js,它显示了ReadFileContext对象的实现,我们可以看到它通过块读取fs.read.这意味着如果主线程被阻塞(你的第二个代码块)或负载极重(你的第三个代码块),处理每8k一次的read回调非常慢,这会极大地影响便利功能的性能:
setInterval呼叫忙等待每100毫秒100毫秒)与readFile实现相结合,在从文件读取的每个8k块之间引入~100ms的延迟.任何大小的文件都需要很长时间才能以~820字节/秒的速度读取.但是,你的测试再次是合成的.即使是一次100毫秒阻塞主线程也是不寻常的.
当我需要读取和写入太多大文件时,我应该使用child_process吗?
号使用基本I/O操作(只要做到这一点的合理大小的块read,write或流),而不是使用像方便的功能readFile.使用子进程至少与使用工作线程一样糟糕,如果不是更糟,Node.js开发团队在工作线程文档中有这个说法:
worker对于执行CPU密集型JavaScript操作很有用; 不要将它们用于I/O,因为Node.js用于异步执行操作的内置机制已经比工作线程更有效地处理它.
| 归档时间: |
|
| 查看次数: |
645 次 |
| 最近记录: |