处理器内核如何共享/运行排队线程?



我有一个有两个内核c1和c2的处理器。我有七个线程 t0、t1、t2、t3、t4、t5 和 t6。t0 是主线程。

从 t0开始,我创建了 t1 和 t2 来处理从 t0 获得的数据 d0 中的某些任务。t1 和 t2 都工作以生成数据 d0a 和 d0b,然后它们馈送到主线程以产生 d0a + d0b = 数据 d1(即线程 t1 和 t2 等待 (join()) 彼此空闲,然后与主线程共享它们的英特尔(从 d0 获得的 d0a 和 d0b)以产生 d1)。

为了帮助加快 t1 处的进程,它会生成线程 t3 和 t4 以帮助生成 d0a,同样,t2 处的进程也会生成 t5 和 t6 以帮助生成 d0b。

假设 c1 处理t1、t3 和 t4,然后 c2 默认处理 t2、t5 和 t6

在t3 和 t4 的帮助下说 t1,在 t2 处开始处理之前生产 d0a 完成。c1 会帮助 c2 在 t2 处完成进程,例如通过处理它的子线程之一(t5 或 t6)。

只要分配给它们的线程空闲,处理器内核是否可以启动排队的线程。

这个问题特别被标记为java和windows,因为我对它如何应用特别感兴趣。也欢迎其他答案

处理器内核可以启动排队的线程吗...

处理器内核对线程一无所知。处理器内核执行指令流。这就是他们所做的一切。

操作系统调度程序知道线程,特别是它知道每个线程的操作状态。在一些假设的操作系统中,有称为running的状态,runnable(线程想要运行,但它缺少 CPU 来运行)和blocked(线程正在等待某些东西)。在真实的操作系统中,可能会有不同类型的blocked,也可能有其他状态,如dead,但我们不需要在这里谈论这些。

操作系统还具有许多队列†用于保存非running线程的上下文;有一个包含所有runnable线程的运行队列,并且对于线程可能blocked的每个不同原因,通常都有一个不同的队列。(例如,对于每个互斥锁,都有一个线程队列等待获取锁。

操作系统调度程序的工作是决定何时抢某个正在运行的线程 A,并选择不同的线程 Brunnable来取代它。调度程序;

  • 中断(即控制)运行线程 A 的 CPU,
  • 将线程 A 的状态从running更改为runnable
  • 将线程 A 的上下文移动到运行队列的后面,
  • 从运行队列中删除线程 B,
  • 将线程 B 的状态从runnable更改为running
  • 将线程 B 的上下文加载到 CPU 上,并且
  • 让 CPU 返回到执行应用程序代码。

。每当分配给它们的线程处于空闲状态时?

线程永远不会处于空闲状态‡ 线程要么blocked,要么runnable(如果不running)。如果没有可以移动到 CPU 上的runnable线程,则CPU可能处于空闲状态。当 CPU 空闲时,它通常会执行操作系统的空闲循环,如下所示:

while (true) {
putCPUIntoLowPowerState();
}

如上所述,摆脱空闲循环的唯一方法是中断 CPU。


* Java 的Thread.State枚举无法识别runningrunnable之间的任何区别。这两个都包裹在Thread.State.RUNNABLE.此外,Java 将我的blocked拆分为Thread.State.BLOCKED(线程正在等待进入synchronized块)和Thread.State.WAITING(线程正在等待任何其他原因)。

† 实际上不是严格的FIFO队列(感谢@NateEldredge),但"队列"是传统名称。它们是线程在等待它们正在等待的任何内容时驻留在其中的容器。调度程序可以考虑各种因素(例如,线程的优先级),除了线程在决定从一个队列中获取哪个线程并移动到 CPU 或另一个队列时等待的时间。

‡ 我的意思是从操作系统调度程序的角度来看。应用程序可能将其线程之一视为"空闲",但操作系统不知道应用程序线程应该做什么。就操作系统而言,线程要么running,要么runnable,要么blocked

最新更新