C++ 如何将SleepEx与alertable true和总体最小睡眠时间结合使用?
我有以下用例:我的当前线程需要执行C++ 如何将SleepEx与alertable true和总体最小睡眠时间结合使用?,c++,windows,multithreading,winapi,sleep,C++,Windows,Multithreading,Winapi,Sleep,我有以下用例:我的当前线程需要执行操作1,等待一段时间与其他线程协调,然后需要执行 操作2。在等待之间,APC可能需要由该线程处理,因为文件系统事件会将另一个operation1添加到某个队列,以便在当前线程完成operation2后处理。简单的如下所示: while (true) { processOperation1; SleepEx(..., true); processOperation2; } 重要的是,在operation1和operation2之间,必须至少经过Sle
操作1
,等待一段时间与其他线程协调,然后需要执行
操作2
。在等待之间,APC可能需要由该线程处理,因为文件系统事件会将另一个operation1
添加到某个队列,以便在当前线程完成operation2
后处理。简单的如下所示:
while (true)
{
processOperation1;
SleepEx(..., true);
processOperation2;
}
重要的是,在operation1
和operation2
之间,必须至少经过SleepEx
的指定时间!这不需要是一个整体,线程可以立即用于处理APC并对另一个操作1
排队,除非经过指定的时间,否则它不应该继续操作2
从:
如果参数为TRUE,且调用此函数的线程与调用扩展I/O函数(ReadFileEx或WriteFileEx)的线程相同,则当超时时间已过或出现I/O完成回调函数时,该函数将返回。如果发生I/O完成回调,则调用I/O完成函数。如果一个APC被排队到线程(QueueUserAPC),则该函数在计时器超时或调用APC函数时返回
根据我的理解,这意味着如果调用了SleepEx
,并且一个APC已经排队,那么它将直接由当前线程执行,因为它能够这样做。但是在SleepEx
之后的代码会发生什么呢?线程返回到进程operation2
是因为SleepEx
返回了控件,还是返回到睡眠状态,一直保持在SleepEx
中,直到指定的时间过去
文档中的第一句话不是关于从函数返回,而是“恢复线程”:
挂起当前线程,直到满足指定的条件。当发生以下情况之一时,将继续执行:
这可能意味着线程将被恢复,处理APCs,然后停留在SleepEx
,睡眠所需的时间
如果情况并非如此,并且SleepEx
真的离开了,它能告诉我们经过了多少时间吗SleepEx
似乎没有提供该值,但只提供了一些常量返回值。这听起来像是我需要自己在SleepEx
之前和之后花费一些时间,并在循环中一次又一次地调用该函数,直到我真正需要的时间过去了?已经有这样的东西了吗,也许是作为boost
的一部分
谢谢 您应该在循环中调用
SleepEx
,并处理排队的APC,直到所需的超时时间过去
像这样的
for (DWORD dwStart = GetTickCount(); ; )
{
DWORD dwElapsed = GetTickCount() - dwStart;
DWORD dw = (dwTimeout > dwElapsed) ? (dwTimeout - dwElapsed) : 0;
if (!SleepEx(dw, TRUE))
break;
}
这不是一个合理的要求。如果你想最小化延迟,那么不要改变它。让工作线程处理I/O完成是当今IOCP的标准,boost::asio也使用它。如果apc在
SleepEx
-apcSleepEx
之后执行,只需返回控制即可。例如SleepEx(无限,真)
-返回后apc@HansPassant我不想最小化延迟,但我真的想主要在我要求的情况下等待,并想知道如何在使用这些延迟的环境中处理APC。根据目前的答案,您可以简单地使用SleepEx而不是Sleep always,并且不需要关心是否使用了APC。通常,您需要关心是否正在使用APC,因为如果APC正在使用,则执行可警报的等待可能不安全。特别是,如果执行等待的函数是从APC内部调用的,则可能会遇到问题。根据你在问题中所说的,我认为这对你来说不是问题,但我想我应该提一下以防万一。PS:根据你的情况,processOperation1()和processOperation2()作为APC本身可能更为优雅,processOperation2()通过一个调用。