我记得在我上大学的课程中,我最喜欢的一个竞赛条件示例是其中一个简单的main()
方法启动了两个线程,其中一个线程增加了一个共享(全局)一个变量,另一个递减。伪代码:双CPU机器上的线程合作
static int i = 10;
main() {
new Thread(thread_run1).start();
new Thread(thread_run2).start();
waitForThreads();
print("The value of i: " + i);
}
thread_run1 {
i++;
}
thread_run2 {
i--;
}
教授接着问什么i
值一百万十亿数不胜数运行之后。 (如果它基本上是10以外的任何东西)。不熟悉多线程系统的学生回答说,100%的时间,print()
声明总是将i
报告为10.
这实际上是不正确的,因为我们的教授表明,作为3条语句的每个增量/减量语句实际上编译(组装):
1: move value of 'i' into register x
2: add 1 to value in register x
3: move value of register x into 'i'
因此,i
的值可以是9,10或11(I不会进入细节。)
我的问题:
这是(是?)我的理解是物理寄存器集是特定于处理器的。在使用双CPU机器时(注意双核和双CPU之间的区别),每个CPU都有自己的一组物理寄存器吗? 我以为答案是肯定的。
在单CPU(多线程)机器上,上下文切换允许每个线程拥有自己的虚拟寄存器集。由于双CPU机器上有两套物理寄存器,因此不会因竞争条件而导致更大的潜在可能性,因为您可以从字面上同时运行两个线程,而不是单线程上的“虚拟”同时操作, CPU机器? (虚拟同时操作是指参考每个上下文开关保存/恢复寄存器状态的事实)。
更具体地说 - 如果你是在一个8-CPU机器上运行它,每个带有一个线程的CPU都是竞态的条件消除了?如果将此示例展开为使用8个线程,则在双CPU机器上,每个具有4个内核的CPU可能会增加或减少竞争条件? 操作系统如何防止装配指令的step 3
在两个不同的CPU上同时运行?
被选为多CPU和多核之间差异的答案,以及关于在单核上失败的注释。甚至没有考虑过,这是一个很好的观点。 – 2011-04-03 23:35:50