gpt4 book ai didi

node.js - 关于nodejs线程的一些困惑

转载 作者:太空宇宙 更新时间:2023-11-03 22:44:01 24 4
gpt4 key购买 nike

我对 nodejs 线程有一些困惑。

据我所知,nodejs 在单线程中运行。如果有异步函数被调用,nodejs将创建一个新线程来运行这些异步代码。异步代码完成后。 事件循环将获取异步结果并在另一个新线程中触发回调函数。

为了测试,我进行了如下代码测试:

var fs = require("fs");

fs.readFile('package.json','utf-8', function (err, data) {
if(err)
console.log(err)
else
console.log(data);
});

console.log("before loop");
while(true);
console.log("after loop");

我的预期结果是:

before loop
-- package.json content --

实际上得到:

before loop

我可能有些地方是错的。

问题:

  1. 为什么 while(true) 阻止了 readFile() 或阻止了它的回调函数?
  2. 这些线程之间有什么关系?

最佳答案

您是正确的,nodejs 在单线程中运行。您可以启动单独的进程并在这些进程前面放置一个负载平衡器以利用多核处理器,但这在 Node 本身中并未实现。

但是, Node 不会为它遇到的每个异步函数启动一个线程。它将这些函数调用放入不断运行的事件循环中。这里重要的是事件循环是非阻塞的,这意味着不能保证函数调用执行的顺序 - 这就是为什么回调是所有 Node.js 程序的基础的原因。这意味着,例如,当一个函数正在等待在文件系统中找到文件并将其读取到缓冲区时,事件循环不会停止所有操作以等待其完成并继续进行下一个调用。但这绝不是多线程行为。事件循环并不并行执行任何事情,它只是不断地在任务之间切换。这只是多任务处理:)

在您的示例中, while(true) 正在阻止事件循环,因为它不是异步函数调用。不要忘记,并非 javascript 中的所有内容都是异步的 - 只有函数调用可以是异步的,而其他语言结构则不然,例如循环或条件。因此,在您的示例中,您运行异步文件读取器,该读取器被添加到事件循环并启动。当文件系统正在做它的事情时,事件循环什么都不做,并继续处理 console.log("before loop") 消息。之后,您可以使用 while(true) 循环阻止事件循环。这意味着事件循环不能再将其搁置并转到文件读取器。

希望事情能够解决。这里的主要要点是,并非 javascript 中的所有内容都是或必须是异步的,但处理不同设备(例如文件系统或网络)的大多数耗时操作都是以非阻塞方式实现的。异步函数仅在使用某些外部组件时才有意义 - 您不会使用异步平方根函数,因为它同样会阻止事件循环。这就是为什么不建议将 Node.js 用于繁重的计算操作(例如音频/视频编码)的原因 - 异步优势在这里没有意义。

关于node.js - 关于nodejs线程的一些困惑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37316728/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com