Javascript Node.js API函数是否在单独的线程中执行
Javascript是单线程的。因此,我编写的每一段代码都在节点提供的javascript运行时的一个线程中执行。因此,当我执行以下代码时:Javascript Node.js API函数是否在单独的线程中执行,javascript,node.js,multithreading,Javascript,Node.js,Multithreading,Javascript是单线程的。因此,我编写的每一段代码都在节点提供的javascript运行时的一个线程中执行。因此,当我执行以下代码时: var fs = require("fs"); fs.readFile('input.txt', function (err, data) { if (err) { return console.error(err); } console.log("Asynchronous read: " + data.toString(
var fs = require("fs");
fs.readFile('input.txt', function (err, data) {
if (err) {
return console.error(err);
}
console.log("Asynchronous read: " + data.toString());
});
// Synchronous read
var data = fs.readFileSync('input.txt');
以下是我对工作流程的理解,如果我错了,请纠正我:
节点中的manager立即将fs.readFile
从调用堆栈弹出,并移动到其他线程,在那里开始读取内容
读取完成后,节点中的管理器:
- 将
fs.readFile
的回调函数放入队列堆栈中
- 哪个事件循环最终放入调用堆栈并执行
fs.readFileSync
不会从堆栈中弹出,而是像任何其他函数一样在运行时线程中执行
那么,在节点中执行其他线程中的节点API I/O函数并管理其调用堆栈的管理器是谁呢
那么Node是否在后台使用多核来执行其API函数呢?在寻找参考资料时,我实际上找不到任何详细信息。这里有一个很好的介绍和一些关于事件循环如何工作的细节
似乎V8引擎内部还有另一个线程管理事件循环。这将获取操作系统I/O之类的响应,并将数据和相关回调添加到队列中。每次事件循环完成它正在做的事情时,它都会从队列中选择下一件事情。NodeJS正在使用事件循环进行异步操作
如果您知道,存在一个名为libuv的库。libuv负责异步代码执行。下面是一个小伪代码,它是如何管理的:
while there are still events to process:
e = get the next event
if there is a callback associated with e:
call the callback
您可以在此处阅读有关libuv的更多信息-
因此,基本上:
Node.js API函数是否在单独的线程中执行
是和否。如果函数可以将I/O操作移动到线程池中的独立线程,则为是。否则它将在同一线程中执行
那么,谁是节点中执行其他线程中的节点API I/O函数并管理其调用堆栈的管理器呢
libuv-
那么节点是否使用多核在后台执行其API函数呢
我不确定,若我错了,任何人都可以纠正我,但节点是在单核内执行的。如果您希望使用多核支持运行,则需要在群集模式下运行它
UPD:这里有一个小图表可以帮助你理解。
不需要单独的线程。底层操作系统本质上起到“其他”线程的作用,并在I/O操作进行/完成时向节点进程发出信号。@指向从调用堆栈中弹出fs.readFile以便其他函数可以执行的内容,它们是否是执行节点API函数的单独调用堆栈?没有“弹出”它从调用堆栈中返回,而不是在启动I/O操作后立即返回。(它使用操作系统异步I/O调用来完成其工作。)@Pointy这是有道理的,但将其回调放入队列堆栈中,以及SetTimeOut()如何呢节点运行时管理回调等。其核心是一个(可能相当复杂的)循环,使用操作系统轮询设施、计时器等。当低级别发生事件时,运行时必须将其映射到某段用户代码并调用它。这是一个很好的答案。在集群模式下,node实际上是通过创建多个进程来使用多个核心(而不是线程)来工作的。是的,所以如果您想在线程(而不是进程)中运行NodeJ,您可以查看NodeJ的fork-JXCore-。JXCore公开了在不同线程中运行函数的API,并实现了它们之间的消息传递。