【问题标题】:WaitForSingleObject doesn't timeoutWaitForSingleObject 不会超时
【发布时间】: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 附近休眠。这是由于其他线程的时间片以及其他进程的所有其他线程的时间片!

标签: c++ multithreading winapi


【解决方案1】:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-04
    • 2014-07-06
    • 2012-05-17
    • 1970-01-01
    • 2011-05-11
    • 2010-09-17
    相关资源
    最近更新 更多