为什么2个线程递增一个变量会导致不同的输出

时间:2015-08-21 16:28:33

标签: c multithreading concurrency

我刚开始学习并发编程,即使我对此有一个模糊的想法,为什么两个线程递增一个变量会产生不同的输出?

假设变量i是全局的,并且有两个线程试图

i = i + 1;

为什么输出可以是1还是2? 假设主线程没有退出,因为我知道有可能主线程在其中一个线程能够执行任何操作之前退出。

1 个答案:

答案 0 :(得分:8)

因为添加操作是not atomic

来自wikipedia

  

在并发编程中,操作(或一组操作)是   如果系统的其余部分看起来是瞬间发生的,则为原子。

     

原子性是与并发流程隔离的保证。

记住这一点,请考虑以下(简化)插图。操作i = i + 1由三个原子操作组成:

  • 从内存中读取i的当前值
  • 将1添加到已读取的值
  • i写回内存

当两个线程尝试执行i = i + 1时,它们可能都获得相同的当前值i,然后将其设置为i + 1,使其看起来只有1 }增加了。考虑以下两种可能的情况:

场景1

int i = 0;
i = i + 1;

Thread 1: Reads i       // Reads 0
Thread 1 : i = i + 1    // Adds 1 to i
Thread 1: Write i = 1   // Makes i == 1
Thread 2: Reads i;      // Reads 1
Thread 2: i = i + 1     // Adds 1 to i, making i == 2
Thread 2: Write i = 2   // Makes i == 2

// Finally, i becomes 2

在上面的场景中,一切都按预期工作。但是,当线程2在线程1写入i的值<?p>之前读取线程2时会发生什么

场景2

int i = 0;
i = i + 1;

Thread 1: Reads i       // Reads 0
Thread 1 : i = i + 1    // Adds 1 to i
Thread 2: Reads i;      // Reads 0 - NOT 1 because it's not written to memory yet
Thread 1: Write i = 1   // Makes i == 1
Thread 2: i = i + 1     // Adds 1 to i, making i == 1 (Remember, thread 2 had read 0)
Thread 2: Write i = 1   // Makes i == 1

// i is finally 1, instead of 2