在 SleepEx 期间处理了多少 APC?

How many APCs are processed during SleepEx?

这与 of mine about how SleepEx actually works. The docs 说,每当 APC 排队时恢复执行 SleepEx 的线程,并且当线程已经执行 APC 时,APC 可能继续排队。

那么线程持续执行 APC 多长时间?是不是每次检查时队列为空,在那一刻 SleepEx returns 控制权交给调用者?或者该线程只执行一个 APC,那么 SleepEx returns 和另一个 APC 执行将需要 SleepEx 再调用一次?

第一次感觉APC一直执行到队列为空。谢谢!

APC 一直执行到队列为空。当您的代码 return 从 APC 编辑时 - 系统检查是否插入了另一个 APC - 如果是 - 执行下一个 APC,直到线程中不再插入 APC。在此之后 SleepEx(或任何其他可提醒的等待 api)return 控制权交给您


APC 以下一种方式执行 - 当您调用某些 api(SleepExMsgWaitForMultipleObjectsExWaitForSingleObjectExWaitForMultipleObjectsEx .. bAlertable 参数设置为 TRUE)内核检查是否在线程对象中插入 APC。如果是 - 内核将用户模式线程上下文复制到它的堆栈,而不是更改线程上下文(用户模式 ​​return 地址设置为 ntdll.KiUserApcDispatcher)和 return。结果代码 return 不是从他进入内核的地方(如果 SleepEx 这是内部调用的 ZwDelayExecution)而是 KiUserApcDispatcher。这个 api 执行 APC 然后调用 ZwContinue。此 api 声明为:

NTSYSAPI NTSTATUS NTAPI ZwContinue(PCONTEXT Context, BOOLEAN TestAlert);

in place Context uses saved in stack thread context, for return to the point, from which alertable api was called, and TestAlert specifies whether should check for additional apc inserted .如果使用 TestAlert == FALSE 调用 ZwContinue 系统将不再检查线程队列中的 APC,直到您自己不调用 SleepEx 或其他某些 api - 因此将恰好执行 1 个 APC .但在 KiUserApcDispatcher TestAlert 中硬编码为 TRUE - 如果理解汇编代码(KiUserApcDispatcher 很小)

,您可以自己轻松查看