WaitForThreadpoolWaitCallbacks立即返回,无需等待

时间:2013-05-07 08:38:19

标签: c++ multithreading winapi threadpool wait

我在这里做错了WaitForThreadpoolWaitCallbacks立即返回而不等待?

HANDLE hEvent = CreateEvent(0, FALSE, FALSE, 0);
...
PTP_WAIT Pwa = CreateThreadpoolWait(WaitCallback, NULL, NULL);
SetThreadpoolWait(Pwa, hEvent, NULL);
// Here we should wait until hEvent gets signaled
WaitForThreadpoolWaitCallbacks(Pwa, FALSE);
// Here we should get after hEvent gets signaled

WaitForThreadpoolWaitCallbacks永远不会等待,并且在WaitForThreadpoolWaitCallbacks之后立即继续执行。但是,如果事件发出信号,则仍会以任何方式调用回调。无论之前是否调用过WaitForThreadpoolWaitCallbacks,事件也会发出信号。

在SetThreadPoolWait中,Timeout设置为NULL以永远等待。

  

指向FILETIME结构的指针,指定绝对值或   等待操作应该超时的相对时间。如果这   参数指向正值,表示绝对时间   自1601年1月1日(UTC)起,以100纳秒为间隔。如果这   参数指向负值,表示时间量   等待相对于当前时间。有关时间的更多信息   值,请参阅文件时间。

     

如果此参数指向0,则等待立即超时。如果这   参数为NULL,等待不会超时。

编辑:似乎SetThreadpoolWait的调用本身不会将线程池等待项(PTP_WAIT)设置为挂起状态。如果是这种情况,WaitForThreadpoolWaitCallbacks将等待CancelPendingCallbacks参数设置为FALSE。也可能出现“取消待定”一词具有误导性的情况。待定也可能意味着事件已经等待已经发出信号,但是没有自由工作线程来启动回调方法。

另一个不太可能的原因可能是WaitForThreadpoolWaitCallbacks有问题。

1 个答案:

答案 0 :(得分:0)

似乎可能存在比赛条件:

来自MSDN Magazine

要注意的是,只有在发出信号通知相关联的同步对象或超时到期时,等待对象才会在回调中排队。在这些事件之一发生之前​​,不会有任何回调排队,也没有等待函数等待。解决方案是先用空指针值调用SetThreadpoolWait,告诉wait对象停止等待,然后再调用WaitForThreadpoolWaitCallbacks以避免任何竞争情况:

SetThreadpoolWait(w.get(), nullptr, nullptr);
WaitForThreadpoolWaitCallbacks(w.get(), TRUE);