最近看了Reactos中
WaitforSingleObject
函数的实现代码:https://github.com/reactos/reactos/blob/master/ntoskrnl/ke/wait.c
遇到一个问题:一个线程如何在不考虑APC的情况下跳出这个函数中的while循环?
假设一个线程调用
WaitforSingleObject
并卡住等待一个信号量对象,这个函数中循环的简化逻辑是:检查信号量的值->卡住等待->被唤醒->检查信号量的值信号量 -> 卡住等待...
我的问题是在“唤醒”这一步(另一个线程调用
NtReleaseSemaphore()
->KiUnWaitTest()
),已经有一个信号量减值的操作,因为唤醒一个线程需要消耗一个值,因此,假定信号量的值从 1 更改为 0。被唤醒的线程进入一个新循环,检查信号量的值,并且因为它为零,所以返回等待。这个过程不是没完没了吗?是不是好像跳不出这个死循环似的?
仔细阅读了Reactos中waitforsingleobject函数的实现代码:https://github.com/reactos/reactos/blob/master/ntoskrnl/ke/wait.c