std :: thread不退出

时间:2019-06-24 15:04:28

标签: c++ multithreading

我有充当某种反空闲CPU状态的代码。在笔记本电脑上,装有USB摄像头,可以抓取图像,如果允许CPU进入空闲状态,则会丢失图像。由于我没有相关系统的管理员权限,因此我运行了一个仅对整数执行愚蠢++的线程,以保持CPU空闲(以及100%使用率的1个内核)。问题是,在相关系统上,代码永远不会退出。在我的开发系统上,代码将正常退出,在应运行应用程序的系统上,代码可以正常运行,但永远不会退出。

我在控制台中得到的输出是

Setting bool to exit.
Reached join 1.
Reached join 2.

就这样。不会发生退出,因此AntiIdle上的join()不会返回。为什么?在一个系统上,它不会,在另一个系统上,它不会。

bool g_ExitProgram = false;

void AntiIdle()
{
    int32_t ch = 0;
    while (!g_ExitProgram)
    {
        ch++;
    }
}

main()
{
    std::thread antiIdleThread(AntiIdle);
    while (!g_ExitProgram)
    {
        if (_kbhit())
        {
            char ch = _getch();
            switch (ch)
            {
            case 27:
                printf("Setting bool to exit.\n");
                g_ExitProgram = true; break;
            default:
                ;
            }
        }
    }

    printf("Reached join 1.\n");
    displayThread.join();
    printf("Reached join 2.\n");
    antiIdleThread.join();

    printf("Exiting code.\n");
    return 0;
}

编辑:请注意,displayThread具有完全相同的退出条件,中间只有几个sleeps(),等待下一个图像到达。

1 个答案:

答案 0 :(得分:5)

这是一场数据竞赛,因为全局标记上根本没有同步。

最简单的解决方案是将标志更改为std::atomic_bool-默认的顺序一致性将起作用,在这种情况下,您可能不需要对其进行优化。

documentation而言,std::atomic具有默认的顺序一致性,或者更宽松的store(memory_order_release) / load(memory_order_acquire)会给您release-acquire ordering

仅出于完全清楚的目的,将标志volatile 不解决此问题。它可能适用于Java,但不适用于C ++,并且从未如此。如果您很不幸,它会出现 足够长时间,以使您遇到麻烦。