123kkk
回答者
回答于 2026-10-17
在C++ Windows编程中,Sleep与SleepEx的核心差异在于线程挂起期间是否允许被异步过程调用(APC)中断。
直接回答
Sleep函数:将当前线程无条件挂起指定的毫秒数。挂起期间线程处于不可警告状态,不会被排入队列的APC中断,超时后恢复执行并返回0。SleepEx函数(bAlertable为FALSE):行为与Sleep完全一致,线程不可被APC中断,超时后返回0。SleepEx函数(bAlertable为TRUE):线程进入可警告等待状态。若在超时前有线程的APC被排入队列(如通过QueueUserAPC或异步I/O完成例程),线程会被提前唤醒以执行该APC,随后SleepEx返回WAIT_IO_COMPLETION而非0;若无APC触发,则在超时后正常返回0。
判断依据
- 返回值区分:
Sleep无返回值(void)。SleepEx返回DWORD,值为0表示超时结束,值为WAIT_IO_COMPLETION(即192)表示因APC而提前唤醒。 - 底层机制:Windows内核中,
bAlertable参数决定了线程等待对象是否包含WaitMode为KernelMode之外的用户模式APC分发条件。
适用条件
- 需要在线程休眠期间响应异步I/O完成通知或自定义APC回调时,必须使用
SleepEx(TRUE)。 - 仅需简单延时且不希望被任何异步事件打断时,使用
Sleep或SleepEx(FALSE)。
常见误区
- 误认为
SleepEx(TRUE)等同于Sleep加定时器回调。实际上APC的执行依赖于线程处于可警告等待状态,普通Sleep无法触发已排队的APC。 - 忽略
SleepEx的返回值检查。当bAlertable为TRUE时,若不判断返回值是否为WAIT_IO_COMPLETION,可能导致后续逻辑在未完整休眠的情况下错误执行。