当硬件有 4 个核心且软件应用程序有超过 4 个线程时,多线程如何工作

当硬件有 4 个核心且软件应用程序有超过 4 个线程时,多线程如何工作

假设我有一个 4 核 4 线程的处理器和一个有 20 个线程的应用程序,我需要它们进行持续检查(假设它们是事件),处理器如何在线程数量有限的情况下同时运行所有线程?我知道处理器在一个线程和另一个线程之间切换,由于切换速度非常快,我们无法注意到,但这就是发生的一切还是计算机做了其他事情。此外,计算机如何在某个时间点将每个线程的信息保存在 RAM 内存中?

答案1

20 个线程不可能同时运行,除非系统有 20 个或更多内核。系统能做的就是让它就像他们几乎同时奔跑一样。

这就是操作系统调度程序的用途。

在多核处理器出现之前,操作系统必须在多个进程之间共享 CPU 时间,每个进程都有可能拥有多个不同的线程。

操作系统必须管理每个线程,为其分配一定量的 CPU 时间,恢复状态,运行线程,暂停和保存状态。这些在多核、多 CPU 或单核之间没有太大区别。

变化的是复杂程度和可以同时运行的线程数。以前我们一次只能运行一个线程,现在可以运行四个。跟踪线程状态的过程相同(程序计数器等),程序有多少个线程并不重要。

操作系统将尝试根据线程是否有工作要做(可能是在等待硬件中断或磁盘中的某些数据)、进程/线程的优先级以及一大堆其他因素,公平地安排所有线程在 CPU 上的时间。线程可以通知操作系统它们没有工作要做,直到发生各种事件,这些事件可能是时间、硬件或软件事件等。在这种情况下,操作系统调度程序可以简单地跳过该线程,直到找到准备好执行某些工作的线程。

目前我使用的系统报告所有正在运行的进程中有 2500 个线程,显然它们不可能在 4 核处理器上同时运行。

答案2

首先:CPU 并不“有”线程,尽管营销人员试图声称这一点。CPU能跑最多可同时运行指定数量的线程。具体而言,具有n未启用核心和超线程可以运行n线程。具有n核心和超线程启用可以运行 2_n_ 个线程。在技术上下文中,我们将“可以运行线程的东西”称为逻辑处理器或 LP。未启用 HT 的机器每个核心有一个 LP;HT 则为其提供两个。

典型的 Windows 系统一次总共有数百甚至数千个线程。这取决于每个程序的代码。当您创建一个进程时,该进程总是以一个线程开始。一些简单的程序,特别是命令行(字符模式)程序,可能只使用一个线程。但在第一个线程中运行的代码可以创建其他线程,并且那些线程可以创建其他线程,依此类推,几乎没有实际限制。有充分的理由不简单地创建大量线程,但没有任何东西可以阻止创建远远超过一个线程用途的线程。

(在 x86 上,使用线程堆栈大小的默认值,每个进程的线程数限制在 2000 个左右 - 这是由地址空间限制造成的。)

在任务管理器的“详细信息”选项卡中,您可以启用“线程”列,它将告诉您当前每个进程中有多少个线程。这是一个 PowerShell 命令,它将计算系统中的所有线程:

($threads = get-ciminstance win32_thread).count
3437

这是一台具有四个超线程核心、总共八个 LP 的机器。

这不是问题,因为实际上只有极少数线程想要随时运行。大多数进程中的大多数线程大部分时间都处于 Windows 所称的“等待”状态,这意味着它们目前不想或无法使用 CPU 时间。它们正在等待 I/O(可能是网络、可能是磁盘等)完成,它们正在等待用户输入,它们正在等待其他线程释放它们需要访问的资源等。(*nix 派生系统将此称为“阻塞”。)

如果您想知道正在等待的线程数,请尝试以下操作:

PS C:\Users\jeh> ($threads = get-ciminstance win32_thread | where-object -Property ThreadState -EQ 5).count
3427

因此,目前看起来只有 10 个线程尝试使用 LP。但情况甚至比这更好。对于 8 个 LP,其中 8 个线程是系统的空闲线程。每个 LP 都有一个专用的空闲线程。它们始终准备运行,但只有在没有其他线程需要 LP 时才会运行。因此,在我执行上述命令时,只有两个“真实”线程想要工作。空闲线程的活动是不是包含在任务管理器的 CPU 利用率折线图显示中。

注意:这些数字并不十分准确,因为这些 Powershell 和 WMI 操作在内部与操作系统的功能不同步。但它们足够接近,足以说明这一点。

如果“就绪”的线程(空闲线程除外)多于 LP,则调度程序通常会选择最高优先级非线性规划线程 - 根据最近在哪个 CPU 上运行的线程进行一些调整。如果多个线程具有相同的优先级,则它们可能会被“时间分片”,以“循环”方式运行,每个线程运行 20 或 60 毫秒,然后调度程序将 LP 切换到另一个线程。

这里是我给出的一个答案,其中更详细地介绍了 Windows 中线程优先级的工作方式。

相关内容