Node.JS 内核模式线程

标签 node.js

我试图弄清楚 Node.JS(其 Windows 版本)是如何在幕后工作的。

我知道有用户态和内核态线程,我知道处理模型是这样的:

enter image description here

我也知道从内核模式线程移动到用户模式线程被认为是上下文切换。

Node.JS C++ 非阻塞工作线程是内核模式吗?在内核模式或用户模式下,单个事件循环线程位于何处?

最佳答案

如您所知,node.js 具有单线程架构。 JavaScript 环境和事件循环仅由单个线程管理,在内部,所有其他线程均由 C++ 级别的线程池处理(类似于由 libuv 线程处理的异步 I/O)。

为了回答您的问题,这些 node.js C++ 非阻塞工作线程不是内核模式。它们是用户模式。事件循环线程也是用户模式。线程在需要时请求内核模式。

当 CPU 处于内核模式时,假定它正在执行受信任的软件。内核模式是最高权限级别,代码可以完全访问所有设备。在 Windows 中,只有 Windows 开发人员编写的选定文件才能完全在内核模式下运行。所有用户模式软件都必须通过系统调用请求使用内核,以便执行特权指令,例如进程创建或 I/O 操作。

所有进程都是从用户态开始执行的,只有在获得内核提供的服务时才会切换到内核态。这种模式变化称为模式切换,而不是上下文切换,即 CPU 从一个进程切换到另一个进程。

我希望您清楚,即使是用户模式线程也可以通过系统调用执行特权操作(网络访问),并在完成所需任务后返回用户模式。 Node.js 仅使用系统调用。

来源:http://www.linfo.org/kernel_mode.html

更新

我应该提到模式切换并不总是意味着上下文切换。引用 wiki :

When a transition between user mode and kernel mode is required in an operating system, a context switch is not necessary; a mode transition is not by itself a context switch. However, depending on the operating system, a context switch may also take place at this time.

你说的也对,模式切换会导致上下文切换。但它并不总是发生。每当发生模式切换时,都不希望进行上下文切换(严重的性能损失)。 Windows 内部发生了什么很难说,但很可能模式切换不会每次都导致上下文切换。

关于一对一的线程模型。 Windows 和 Linux 都遵循这一点。因此,给定每个用户线程(如 node.js 事件循环线程)操作系统提供一个内核线程,它负责系统调用。 Node.js 只能通过系统调用调用模式切换。上下文切换仅由内核(线程调度程序)控制。

更新2

是的,HTTP.SYS 在内核模式下执行。但还有更多。 Node.js 没有很多线程,因此与 IIS 不同,线程之间发生的上下文切换较少。每个请求的上下文切换(模式切换)在HTTP.SYS中肯定是少了。这是对过去的改进(恰好是一场灾难),参见 here .多线程带来的上下文切换远不止使用HTTP.SYS减少上下文切换。所以总体上 node.js 的上下文切换更少。

HTTP.SYS 与 Node 自身的 HTTP 实现相比还有其他优势,这有助于 IIS .可能(将来)从 Node 本身使用 HTTP.SYS 来利用这些优势。但就目前而言,我认为 HTTP.SYS/IIS 无法与 node.js 竞争。

关于Node.JS 内核模式线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16707098/

相关文章:

node.js - Node JS-MongoDB : use an opening connection

javascript - 如何处理环回传入的 http 请求

node.js - 使用 NodeJS 逐帧处理视频

node.js - 使用 Mongoose 模式获取嵌套数组引用?

javascript - 我的私有(private)消息不适用于 socket.io

node.js - Jest 测试失败时如何打印请求和响应?

node.js - AWS Lambda 任务在 3.00 秒后超时

node.js - 在 Express Node 应用程序中使用 connect-livereload

node.js - 是否有可能做到这一点? (涉及解构和重新分配)

android - 来自前后摄像头的 FFmpeg 视频连接创建视频翻转