我正在试图弄清楚Node.JS(其Windows版本)是如何在幕后工作的。
我知道有用户模式和内核模式线程,我知道处理模型如下所示:
我也知道从内核模式线程转移到用户模式线程被认为是上下文切换。
Node.JS C ++非阻塞工作线程是否是内核模式?单个事件循环线程在内核模式或用户模式下的位置在哪里?
答案 0 :(得分:7)
如您所知,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:
当需要在用户模式和内核模式之间进行转换时 操作系统,不需要上下文切换;模式转换 本身不是一个上下文切换。但是,视操作而定 系统,此时也可以进行上下文切换。
你提到的也是正确的,模式切换可以导致上下文切换。但它并不总是发生。无论何时发生模式切换,都不希望有上下文切换(严重的性能损失)。 Windows内部发生的事情很难说,但最有可能的模式切换不会每次都导致上下文切换。
关于一对一线程模型。 Windows和Linux都遵循这一点。因此给定每个用户线程(如node.js事件循环线程)OS提供了一个内核线程,它负责系统调用。 Node.js只能通过系统调用调用模式切换。上下文切换仅由内核(线程调度程序)控制。
是的,HTTP.SYS在内核模式下执行。但还有更多。 Node.js没有很多线程,因此与IIS不同,线程之间的上下文切换次数较少。在HTTP.SYS中,每个请求的上下文切换(模式切换)肯定更少。这是过去的改进(恰好是一场灾难),见here。多线程导致的上下文切换远不止使用HTTP.SYS减少上下文切换。因此整体node.js具有较少的上下文切换。
HTTP.SYS还有比节点自己的HTTP实现更有优势,有助于IIS。有可能(将来)从节点本身使用HTTP.SYS来获得这些优势。但就目前而言,我认为HTTP.SYS / IIS不会在node.js附近竞争。