我有充当某种反空闲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(),等待下一个图像到达。
答案 0 :(得分:5)
这是一场数据竞赛,因为全局标记上根本没有同步。
最简单的解决方案是将标志更改为std::atomic_bool
-默认的顺序一致性将起作用,在这种情况下,您可能不需要对其进行优化。
就documentation而言,std::atomic
具有默认的顺序一致性,或者更宽松的store(memory_order_release)
/ load(memory_order_acquire)
会给您release-acquire ordering。
仅出于完全清楚的目的,将标志volatile
不解决此问题。它可能适用于Java,但不适用于C ++,并且从未如此。如果您很不幸,它会出现 足够长时间,以使您遇到麻烦。