c++ - 我的多线程程序在双核机器上运行缓慢或出现死锁,请帮忙

标签 c++ c multithreading winapi

我有一个有多个线程的程序,一个线程在退出时会更改一个全局变量,另一个线程会重复轮询全局变量。对全局没有任何保护。 该程序在单处理器上运行良好。在双核机器上,它会工作一段时间,然后在 Sleep(0) 或 SuspendThread() 上停止。有人能帮我解决这个问题吗?

代码是这样的:

Thread 1:

do something...
while(1)
{
.....
flag_thread1_running=false;
SuspendThread(GetCurrentThread());
continue;

}

Thread 2
flag_thread1_running=true;
ResumeThread(thread1);
.....do some other work here....
while(flag_thread1_running) Sleep(0);
....

最佳答案

您在单处理器机器上看不到任何问题,但在多处理器机器上看到问题的事实是单处理器机器上线程上下文切换粒度相对较大的产物。在线程调度程序将执行切换到另一个线程之前,线程将执行 N 时间量(毫秒、纳秒等)。许多 CPU 指令可以在典型的线程时间片中执行。您可以将其视为拥有相当大块的“自由发挥”独占处理器时间,在此期间您可能不会遇到资源冲突,因为处理器上没有执行任何其他操作。

但是,当在多进程机器上运行时,两个线程中的 CPU 指令完全同时执行。 “免费游戏”时间 block 的大小接近于零。

要重现两个线程之间的资源争用问题,您需要让线程 1 访问资源,让线程 2 同时或几乎同时访问资源。

在单处理器机器上发生的大粒度线程切换中,线程切换恰好发生在正确位置的可能性很小,因此程序在单处理器机器上正常使用时可能永远不会出现故障。

在多进程机器中,指令在两个线程中同时执行,因此线程 1 和线程 2 同时访问同一资源的可能性要大得多——比线程 1 和线程 2 的可能性高出数千倍单处理器场景。

我已经看到这种情况发生过很多次:在单进程机器上运行多年的应用程序在新的多进程机器上执行时突然开始全面失败。原因是原始代码中存在一个潜在的线程错误,它根本就不会在 uniproc 机器上重现时间片的正确巧合。

使用多线程代码时,绝对不能在多进程硬件上测试代码。如果您的代码中存在线程冲突问题,它们将很快出现在多进程计算机上。

正如其他人所指出的,除非您是一名调试人员,否则不要使用 SuspendThread()。使用互斥锁或其他同步对象在线程之间进行协调。

关于c++ - 我的多线程程序在双核机器上运行缓慢或出现死锁,请帮忙,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2762041/

相关文章:

c++ - 计算两个数组中匹配元素的个数 C++

c++ - 如何阅读 uniform_int_distribution 的概率质量函数?

c - 输入文本文件时文件无法正确输出

c++ - 通过 "inorder"和 "reverse inorder"方法同时遍历二叉搜索树的多线程方法,比较元素对

int 数组中的 C++ 分隔符

c++ - 尽管尝试创建两个线程,但只创建了一个线程

c - %n 如何处理变量

C "pointer being freed was not allocated"错误

java - 一台服务器支持多个客户端 Java

java - ReentrantLock 允许线程多次锁定某个资源