WaitForSingleObject 不会超时

Posted

技术标签:

【中文标题】WaitForSingleObject 不会超时【英文标题】:WaitForSingleObject doesn't timeout 【发布时间】:2016-03-01 06:25:51 【问题描述】:

下面的简单代码没有按我的预期运行。它创建一个线程(暂停),启动它,等待它运行 1 毫秒,然后循环等待直到线程死亡或失败。

我希望输出类似于以下内容:

开始 回调运行 回调运行 回调运行 WaitForSingleObject 循环 回调运行 回调运行 WaitForSingleObject 循环 回调运行 回调运行 WaitForSingleObject 循环 回调运行 回调运行 ... 重复 10000 次 结束 线程结束

但是输出是:

开始 回调运行 回调运行 回调运行 回调运行 回调运行 ... 重复 10000 次 回调运行 结束 WaitForSingleObject 循环 线程结束

我认为WaitForSingleObject 中的等待会在某个时候超时并在某个时候中断线程?但是线程好像是阻塞的而不是异步的?

DWORD WINAPI callback(LPVOID param)

    printf("Start\n");

    for (int i=10000; i>0; i--)
        printf("Callback running\n");

    printf("End\n");
    return 1;


int main()

    HANDLE hThread = CreateThread(NULL, 0, callback, 0, CREATE_SUSPENDED, 0);

    if (!hThread) 
        printf("Failed to create thread\n");
        return 0;
    

    ResumeThread(hThread);
    while (WaitForSingleObject(hThread, 1) == WAIT_TIMEOUT) 
        printf("WaitForSingleObject looping\n");
    

    CloseHandle(hThread);
    printf("Thread end\n");

    system("PAUSE");
    return 0;

【问题讨论】:

在线程终止之前,您的线程不会执行任何放弃 CPU 时间的让步操作。尝试定期调用线程循环调用Sleep(),您将看到操作系统能够定期切换回主线程,以便对超时做出反应。 您还可以增加线程内的旋转次数。计算机速度很快,仅 10k 输出可能比典型线程的时间片要少。在网上搜索那个时间片是什么,它在 MS Windows 系列操作系统中有所不同。此外,WaitForSingleObject()Sleep() 和其他类似的函数通常会在给定时间 至少 休眠!在你的情况下,不能保证它会在 1ms 附近休眠。这是由于其他线程的时间片以及其他进程的所有其他线程的时间片! 【参考方案1】:

WaitForSingleObject 中的 dwMilliseconds 参数不能用于准确计时。唯一的约定是,经过这么长时间后,线程将最终唤醒并返回TIMEOUT 值。线程可能要等到它的下一个计划时间量才会唤醒,时间量可能高达 60 毫秒(在 Windows Server 上甚至更高)。这对于完成第二个线程来说已经绰绰有余了。尝试增加迭代次数,使工作线程至少需要一秒钟才能运行 - 这应该有足够的时间来安排主线程并至少再运行一次 TIMEOUT 循环的迭代。

【讨论】:

以上是关于WaitForSingleObject 不会超时的主要内容,如果未能解决你的问题,请参考以下文章

在 Windows 上使用 WaitForSingleObject 但支持提升线程中断

MFC WaitForSingleObject(hThread,INFINITE)执行过程中程序没有响应了

WaitForSingleObject 与联锁*

跨平台事件处理 - std::condition_variable wait_for 似乎忽略了超时

WaitForSingleObject 死锁

WaitForSingleObject 和 WaitForMultipleObjects函数