并发性如何在nodejs中运行?

Jat*_*tin 9 concurrency multithreading node.js

我试图理解并发如何在像nodejs这样的单线程环境中工作.

假设我有这段代码:

var fs = require('fs');

fs.readFile('file1', function one(err, data) {
  // some code...
});

fs.readFile('/file2', function two(err, data) {
  // some code...
});
Run Code Online (Sandbox Code Playgroud)

现在每个fs.readFile调用都是异步的.所以,它们同时运行.但如果所有这一切都发生在一个线程中,那么并发性是如何实现的呢?是function onefunction two运行在相同或不同的线程?

基本上,node.js如何处理并发?

Tro*_*ott 10

就Node而言,只有一个线程.异步调用被放入事件队列中,并且只在下一个tick上运行.

对于Node传递给C++的代码,所有的赌注都是关闭的.那里可能有也可能没有线程.但它并没有真正影响你.

对我来说最有效的解释是"事情循环究竟什么?" 菲利普罗伯茨,因为他展示的慢动作可视化工具使一切都很清楚(无论如何).

你可以在线试验Philip的工具Loupe.

  • 这是一个很好的视频! (5认同)

Ste*_*e U 7

Node.js 确实使用多个线程来处理 io 用户的封面,但这对用户是隐藏的。应用程序环境(即您的代码)只能访问单个线程,但 Node.js 透明地将 io 移交给单独的线程,而无需用户处理它。

在您的情况下,函数一和函数二都在同一线程中运行,但读取文件数据的实际 io 操作是在不同的线程中执行的。

Node.js的的的线程/ IO模型更详细的描述,可以发现在这里,可以读出一套很好的例子类似这里


npe*_*npe 6

node.js 的事情是一切都同时运行,除了你的代码

所以,这意味着实际上有很多线程在 node.js 虚拟机(或线程池,如果你愿意)中运行,并且当你调用异步函数时会使用这些线程,比如对文件执行 i/o 操作,访问数据库、请求 url 等。

但是,对于您的代码,只有一个线程,它处理来自事件队列事件。因此,当您注册回调时,它的引用实际上会传递给后台工作线程,并且一旦异步操作完成,新事件将通过该回调添加到事件队列中。

  • 虽然有可能将两个任务分配给同一个工作线程,但应该认为这是不太可能的。但它绝对是读取这些文件的工作线程,而不是您的事件循环线程。 (2认同)