线程如何在ReactOS的KeWaitForSingleObject循环中跳出(不考虑APC)
关于ReactOS中KeWaitForSingleObject信号量等待的死循环疑问解答
你担心的死循环情况不会发生,核心原因是唤醒线程的操作和信号量资源的分配是原子绑定的,具体拆解下流程:
线程调用
KeWaitForSingleObject等待信号量时,第一步会尝试快速路径:检查信号量的SignalState是否大于0,如果是,直接原子减1然后返回成功,不会进入等待。只有当SignalState为0时,才会进入等待队列挂起。当其他线程调用
NtReleaseSemaphore增加信号量的SignalState后,KiWaitTest会触发处理等待队列,找到合适的等待线程并调用KiSatisfyObjectWait:- 这个函数会先持有信号量的自旋锁,原子地把
SignalState减1(完成资源分配); - 然后把被唤醒线程的等待状态标记为已满足(比如设置线程的
WaitStatus为STATUS_SUCCESS),同时将线程从等待队列中移除; - 最后唤醒该线程。
- 这个函数会先持有信号量的自旋锁,原子地把
被唤醒的线程回到
KeWaitForSingleObject的循环时,不会再重新去检查信号量的SignalState,而是会先检查自己的等待是否已经被标记为满足。一旦确认等待已满足,就直接跳出循环,返回成功,不会再次进入等待。
简单说,不是“唤醒后再检查资源”,而是“分配资源后再唤醒”——被唤醒的线程已经拿到了信号量的资源,自然不会再回去等待,也就不存在死循环的问题。
内容的提问来源于stack exchange,提问作者lifeng zhang
相关产品推荐
相关产品推荐

