问题
I have the following use case: My current thread needs to do operation1
, waits some amount of time to coordinate with others and afterwards needs to do
operation2
. In between the waiting, APCs might need to be processed by that thread because of file system events, which add another operation1
to some queue to be processed later after operation2
is finished by the current thread. Something simple like the following:
while (true)
{
processOperation1;
SleepEx(..., true);
processOperation2;
}
The important thing is that between operation1
and operation2
at least the specified amount of time to SleepEx
has to be elapsed! That doesn't need to be in one piece, the thread can instantly be used to process APCs and queue another operation1
, it just shouldn't continue with operation2
unless the specified amount of time has elapsed.
From the docs:
If the parameter is TRUE and the thread that called this function is the same thread that called the extended I/O function (ReadFileEx or WriteFileEx), the function returns when either the time-out period has elapsed or when an I/O completion callback function occurs. If an I/O completion callback occurs, the I/O completion function is called. If an APC is queued to the thread (QueueUserAPC), the function returns when either the timer-out period has elapsed or when the APC function is called.
From my understanding that means that if SleepEx
is called and an APC has been queued, that is directly executed by the current thread because it is capable to do so. But what happens afterwards with the code after SleepEx
? Does the thread return to process operation2
because SleepEx
returned control or does the thread gets back to sleep, staying in SleepEx
until the specified amount of time is elapsed?
The first sentence in the docs is not speaking about returning from the function, but "resuming the thread":
Suspends the current thread until the specified condition is met. Execution resumes when one of the following occurs:
That could mean that the thread is resumed, processes APCs and afterwards stays in SleepEx
, sleeping for whatever amount of time is needed.
If that's not the case and SleepEx
is really left, does it tell how much time has elapsed? SleepEx
doesn't seem to provide that value, but only some constant return value. This sounds like I would need to take time before and after SleepEx
on my own and call that function again and again in a loop until the time I need really has elapsed? Is there already something out there like that, maybe as part of boost
?
Thanks!
回答1:
You should call SleepEx
in a loop and process the queued APCs until the needed timeout elapses.
Something like this.
for (DWORD dwStart = GetTickCount(); ; )
{
DWORD dwElapsed = GetTickCount() - dwStart;
DWORD dw = (dwTimeout > dwElapsed) ? (dwTimeout - dwElapsed) : 0;
if (!SleepEx(dw, TRUE))
break;
}
来源:https://stackoverflow.com/questions/46220843/how-to-use-sleepex-with-alertable-true-and-an-overall-minimum-sleep-time