上下文切换是指操作系统需要运行的线程数多于 CPU 内核数。例如,假设您有 10 个线程。他们都很忙(意味着他们都没有完成任务)。但是您的 CPU 只是一个双核 CPU(为简单起见,假设没有超线程)。那么,10 个线程如何全部运行呢?这是不可能的!!
答案是上下文切换。操作系统在出现大量进程和线程要执行时,将为每个线程分配一定的时间来运行。在这段时间之后,操作系统将切换到另一个线程,以便所有线程都有时间使用 CPU。
术语“上下文切换”指的是当操作系统需要将 CPU 分配给另一个线程/进程时,它需要将寄存器中的所有值临时复制到该线程的内存中,否则其他进程/线程将搞砸计算恢复时切换的线程。操作系统还需要重新指向虚拟内存表,以便两个进程不会弄乱彼此的内存。此操作的成本取决于 CPU 架构。Sparc 等一些架构针对上下文切换进行了优化。超线程是一种在硬件中实现上下文切换的功能,因此速度更快(但话又说回来,在 Intel/AMD64 架构上实现的超线程,每个 CPU 只能获得一个额外的上下文)。
不使用多个线程完全避免了上下文切换。特别是如果您的程序是唯一运行的程序。因此,在单核 CPU 上,非阻塞、单线程程序通常可以胜过多线程程序。
但是,如今很难找到单核 CPU。您想要运行的理想线程数等于您拥有的内核数。这样做也可以避免上下文切换。但即便如此,让复杂的多线程程序快速运行也并非易事。让非阻塞单线程程序快速运行更容易。在大多数 Web 应用程序中,多线程程序不会比非阻塞单线程程序有任何优势,因为它们都是 I/O 绑定的。
非阻塞单线程程序基本上是使用事件在用户空间中实现类似线程的行为。在支持使面向事件编程看起来像多线程编程的语法的语言中,这有时被称为“绿色线程”。