给定两个线程并行运行时变量的可能值?

Ruc*_*tel 5 c concurrency multithreading operating-system

问题来自斯坦福大学的试卷它的描述如下:

假设两个线程并发执行以下 C 代码,访问共享变量 a、b 和 c:

初始化

int a = 4;
int b = 0;
int c = 0;
Run Code Online (Sandbox Code Playgroud)

主题 1:

if (a < 0) { 
 c = b - a;
} else {
 c = b + a;
}
Run Code Online (Sandbox Code Playgroud)

主题 2:

b = 10;
a = -3
Run Code Online (Sandbox Code Playgroud)

c两个线程完成后可能的值是什么?您可以假设变量的读取和写入是原子的,并且每个线程内的语句顺序都保留在 C 编译器生成的代码中。

答案:4,7,14,13,-3

我理解前四个输出如下,但我无法理解输出 -3 是如何发生的,因为线程中的语句顺序被保留。

4:执行完线程1,再执行线程2。
7:先中断线程1 c = b + a,再执行线程2,再执行线程1。
14:执行线程2直到b = 10完成,然后中断它,并完全执行线程1。
13:完全执行线程2,然后执行线程1。

现在我被困在如何获得 -3 作为 的最终值c?-3 仅在b=0、 和时可用a=-3,并且线程 1 从 开始执行c = b + a。我认为 -3 在任何其他情况下都不可能。但是正如前面提到的,语句的顺序是保持的,所以 a 的值不能为 -3,除非我们将 b 的值更改为 10。

有人可以解释在这种情况下如何输出 -3 吗?

Goo*_*eds 6

你可以得到-3如下:

  1. 在线程 1 中,检查a < 0,这是错误的。这将带您进入 else 条件。读取 的值b,即0
  2. 切换到线程2,完全执行。a现在是-3
  3. 切换回线程 1, read a,即-3。然后,添加并分配-3c.

  • 根据问题提供的假设,c = b + a 相当于 1. 读取 b,2. 读取 a,3. 添加,4. 写入 c。每次读写都是原子的并不一定意味着整个加法操作都是原子的。 (2认同)
  • @MikePatel,回复,“不应该......自动执行该指令吗?” 请注意您的术语。`c=a+b;` 不是一个“指令”,它是一个 C 语言_语句_。大多数C语言语句将被编译成一系列机器_指令_(例如,将b的值读取到寄存器0中,将a的值读取到寄存器1中,将寄存器1的值添加到寄存器0中,将寄存器0的值存储到c中。) (2认同)