如何在最低级别唤醒休眠线程?

How are sleeping threads woken, at the lowest level?

这个问题我想了很久。

我了解 GUI 编程是事件驱动的。我知道大多数 GUI 程序都有一个事件循环,它循环遍历消息队列中的所有事件。我还了解到它是通过调用某种操作系统方法(如 "get_message()")来实现的,该方法将阻塞线程直到收到消息。从这个意义上讲,当没有事件发生时,线程正在平静地休眠。

但是,我的问题是:操作系统如何检查可用消息?我认为在堆栈的某个地方必须有一个循环不断地检查新事件。这样的循环不可能具有任何阻塞,因为如果是这样,则必须有另一个循环线程'always-awake',准备唤醒第一个。但是,我也很欣赏这不可能是真的,否则我希望看到至少一个处理器核心 100% 一直在使用,一遍又一遍地检查....

我考虑过,也许检查线程在每次迭代之间有一个小的休眠。这肯定可以解释为什么空闲系统没有使用 100% CPU。但后来我想起了事件通常是如何立即得到回应的。以鼠标移动为例:光标不断重绘,与物理移动同步。

当某些内存地址更改值时,CPU 体系结构中是否有一些基本的东西允许在硬件级别唤醒线程?

否则我就没主意了!谁能帮忙解释一下到底发生了什么?

是的,有:硬件中断。

当按下一个键或移动鼠标,或者网络数据包到达,或者从其他设备读取数据,或者定时器到时,OS 接收到硬件中断。

想要执行 I/O 的线程或应用程序必须调用 OS 中的函数,其中 returns 请求数据, , 如果数据尚不可用,则挂起调用线程。这种暂停只是意味着线程不会被考虑进行调度,直到某些条件发生变化 - 在这种情况下,请求的数据必须可用。这样的线程被称为 'IO blocked'.

当 OS 接收到表明某个设备有一些数据的中断时,它会查看它的挂起线程列表,看看是否有一个因等待该数据而挂起的线程,然后删除暂停, 使其符合再次安排的条件。

在这种中断驱动方式中,没有 CPU 时间被浪费在数据上 'polling'。