我有以下用例:我当前的线程需要做operation1
,等待一段时间与其他人协调,然后需要做
operation2
。在等待之间,由于文件系统事件,可能需要由该线程处理APC,这会将另一个operation1
添加到某个队列,以便在当前线程完成operation2
之后处理。简单如下:
while (true)
{
processOperation1;
SleepEx(..., true);
processOperation2;
}
重要的是,在operation1
和operation2
之间至少必须经过SleepEx
指定的时间!这不需要是一个整体,线程可以立即用于处理APC并排队另一个operation1
,它不应该继续operation2
,除非指定的时间量已经过去。
来自docs:
如果参数为TRUE并且调用此函数的线程与调用扩展I / O函数(ReadFileEx或WriteFileEx)的线程相同,则该函数在超时时间段或I / O时返回O完成回调功能。如果发生I / O完成回调,则调用I / O完成功能。如果APC排队到线程(QueueUserAPC),则该函数在超时时间或调用APC函数时返回。
根据我的理解,这意味着如果调用SleepEx
并且APC已经排队,则由当前线程直接执行,因为它能够这样做。但是之后SleepEx
之后的代码会发生什么?线程是否返回进程operation2
,因为SleepEx
返回控制或线程是否重新进入休眠状态,保持在SleepEx
直到指定的时间量过去?
文档中的第一句话不是关于从函数返回,而是“恢复线程”:
暂停当前线程,直到满足指定条件。发生以下任一情况时,执行将恢复:
这可能意味着线程恢复,处理APC,之后停留在SleepEx
,无论需要多长时间都在睡眠。
如果不是这种情况并且SleepEx
真的离开了,它会告诉我们已经过了多长时间吗? SleepEx
似乎没有提供该值,而只提供一些常量返回值。这听起来像我需要在SleepEx
之前和之后花费时间并在循环中一次又一次地调用该函数,直到我需要的时间真的过去了?是否有类似的东西,可能是boost
的一部分?
谢谢!
答案 0 :(得分:4)
您应该在循环中调用SleepEx
并处理排队的APC,直到超过所需的超时时间。
像这样。
for (DWORD dwStart = GetTickCount(); ; )
{
DWORD dwElapsed = GetTickCount() - dwStart;
DWORD dw = (dwTimeout > dwElapsed) ? (dwTimeout - dwElapsed) : 0;
if (!SleepEx(dw, TRUE))
break;
}