每当 CPU 等待某个系统响应(例如等待 Internet 请求)时,就会出现阻塞调用。CPU 在这些调用期间是否真的在浪费时间(我不知道除了 no-op 之外是否还有机器指令与 CPU 真正浪费时间相对应)。如果不是,它在做什么?
3 回答
基本上,内核维护运行队列或类似于调度线程的东西。每个线程都会收到一个时间片,它可以在该时间片中执行,直到它到期或自愿产生它的片。当一个线程产生或它的切片到期时,调度程序决定下一个执行哪个线程。
阻塞系统调用将导致产生。这也将导致线程从运行队列中删除并放入睡眠/挂起队列,在那里它没有资格接收时间片。它将保持在睡眠/挂起队列中,直到满足某些条件(例如计时器滴答声、套接字上可用的数据等)。一旦满足条件,它将被放回运行队列。
Sleep(1); // Yield, install a timer, and place the thread in a sleep queue.
只要任何运行队列中有任务(可能不止一个,通常每个处理器内核一个),调度程序就会继续分发时间片。根据调度程序设计和硬件限制,这些时间片的长度可能会有所不同。
当运行队列中没有任务时,内核可以进入省电状态,直到收到中断。
本质上,处理器从不浪费时间。它要么执行其他线程,服务中断,要么处于省电状态(即使持续时间很短)。
当操作系统调度程序寻找工作以移交给核心时,该线程被简单地跳过。非常普遍的结果是什么都不需要做。然后处理器内核执行 HLT 指令。
在 HALT 状态下,它(几乎)不消耗电力。需要中断才能使其恢复正常。最典型的是时钟中断,默认情况下每秒滴答 64 次。可能是设备中断。然后调度程序再次寻找工作要做。冲洗并重复。
当一个线程被阻塞时,特别是当它被一个有效的等待对象阻塞时,CPU 正忙于为系统中的其他线程提供服务。如果没有应用程序线程在运行,则始终有系统线程在运行。CPU 永远不会真正空闲。