【问题标题】:WaitForThreadpoolWaitCallbacks returns immediately without waitingWaitForThreadpoolWaitCallbacks 立即返回,无需等待
【发布时间】:2013-05-01 03:38:46
【问题描述】:

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,等待不会超时。

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

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

【问题讨论】:

    标签: c++ multithreading winapi threadpool wait


    【解决方案1】:

    似乎可能存在竞争条件:

    来自MSDN Magazine

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

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

    【讨论】:

    • 问题是 WaitForThreadpoolWaitCallbacks 等待任何已排队的回调,但如果尚未设置事件,则没有任何内容排队,也没有什么可等待的。这篇文章谈论的是关闭时的竞争条件,这很有趣,但不是直接的问题。
    猜你喜欢
    • 2015-04-22
    • 1970-01-01
    • 2017-12-15
    • 1970-01-01
    • 1970-01-01
    • 2014-11-04
    • 2013-11-02
    • 2023-02-14
    • 1970-01-01
    相关资源
    最近更新 更多