6

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

我知道有用户模式和内核模式线程,并且我知道处理模型如下所示:

在此处输入图像描述

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

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

4

1 回答 1

9

如您所知,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

更新

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

当操作系统需要在用户模式和内核模式之间转换时,不需要上下文切换;模式转换本身并不是上下文切换。但是,根据操作系统的不同,此时也可能发生上下文切换。

您提到的模式切换可能导致上下文切换也是正确的。但它并不总是发生。每当模式切换发生时,都不需要进行上下文切换(严重的性能损失)。Windows 内部发生的事情很难说,但很可能模式切换不会每次都导致上下文切换。

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

更新2

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

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

于 2013-05-25T14:27:09.797 回答