我有一个带有多个线程的程序,一个线程退出自身时将更改全局,而另一个线程将反复轮询全局。对全局变量没有任何保护。
该程序在单处理器上运行良好。在双核计算机上,它会工作一段时间,然后在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指令可以在典型的线程时间片中执行。您可以将其视为相当大的“自由发挥”专用处理器时间,在此期间您可能不会遇到资源冲突,因为处理器上没有其他任何执行。

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

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

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

在多进程机器中,指令在两个线程中同时执行,因此线程1和线程2同时访问同一资源的机会要大得多,与单处理器情形相比,成千上万倍。

我已经看过很多次了:在Uniproc机器上运行良好多年的应用程序在新的multiproc机器上执行时突然突然开始出现故障。原因是原始代码中潜在的线程错误,根本没有在uniproc机器上实现正确的时间片重合。

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

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

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

10-11 22:54
查看更多