WaitForThreadpoolWaitCallbacks立即返回,而无需等待

问题描述 投票:3回答:1

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中,超时设置为NULL以永远等待。

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

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

Edit:似乎单独调用SetThreadpoolWait不会将线程池等待项(PTP_WAIT)设置为挂起状态。在这种情况下,如果CancelPendingCallbacks参数设置为FALSE,则WaitForThreadpoolWaitCallbacks将等待。 “取消待定”一词也可能会引起误解。待处理还可能意味着已经发出等待事件的信号,但是没有空闲的工作程序线程来启动回调方法。

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

c++ multithreading winapi threadpool wait
1个回答
0
投票

似乎可能存在竞赛条件:

来自MSDN Magazine

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

SetThreadpoolWait(w.get(), nullptr, nullptr);
WaitForThreadpoolWaitCallbacks(w.get(), TRUE);
© www.soinside.com 2019 - 2024. All rights reserved.