1

我是 node.js 的新手。我目前正在阅读Basarat Ali Syed的名为“ Beignning Node.js ”的书。

以下是其中的一段摘录,说明了传统 Web 服务器线程池的缺点:

几年前,大多数 Web 服务器使用线程池这种方法,并且许多服务器今天仍在使用。然而,这种方法并非没有缺点。线程之间再次浪费了 RAM。此外,操作系统需要在线程之间进行上下文切换(即使它们处于空闲状态),这会导致 CPU 资源的浪费。

我不太明白为什么线程池内的线程之间会有上下文切换。据我所知,一个线程将在任务期间持续。并且一旦任务完成,线程就可以自由地接收下一个任务。

所以我的Q1:为什么需要上下文切换?线程之间的上下文切换何时发生?

我的Q2:为什么node.js不使用多线程来处理事件队列中的事件?不是更高效,减少事件的排队时间吗?

4

1 回答 1

1

上下文切换是指操作系统需要运行的线程数多于 CPU 内核数。例如,假设您有 10 个线程。他们都很忙(意味着他们都没有完成任务)。但是您的 CPU 只是一个双核 CPU(为简单起见,假设没有超线程)。那么,10 个线程如何全部运行呢?这是不可能的!!

答案是上下文切换。操作系统在出现大量进程和线程要执行时,将为每个线程分配一定的时间来运行。在这段时间之后,操作系统将切换到另一个线程,以便所有线程都有时间使用 CPU。

术语“上下文切换”指的是当操作系统需要将 CPU 分配给另一个线程/进程时,它需要将寄存器中的所有值临时复制到该线程的内存中,否则其他进程/线程将搞砸计算恢复时切换的线程。操作系统还需要重新指向虚拟内存表,以便两个进程不会弄乱彼此的内存。此操作的成本取决于 CPU 架构。Sparc 等一些架构针对上下文切换进行了优化。超线程是一种在硬件中实现上下文切换的功能,因此速度更快(但话又说回来,在 Intel/AMD64 架构上实现的超线程,每个 CPU 只能获得一个额外的上下文)。

不使用多个线程完全避免了上下文切换。特别是如果您的程序是唯一运行的程序。因此,在单核 CPU 上,非阻塞、单线程程序通常可以胜过多线程程序。

但是,如今很难找到单核 CPU。您想要运行的理想线程数等于您拥有的内核数。这样做也可以避免上下文切换。但即便如此,让复杂的多线程程序快速运行也并非易事。让非阻塞单线程程序快速运行更容易。在大多数 Web 应用程序中,多线程程序不会比非阻塞单线程程序有任何优势,因为它们都是 I/O 绑定的。

非阻塞单线程程序基本上是使用事件在用户空间中实现类似线程的行为。在支持使面向事件编程看起来像多线程编程的语法的语言中,这有时被称为“绿色线程”。

于 2015-10-13T06:35:29.380 回答