需要帮助理解从B.Stroustrup的新书中提取的本文

时间:2014-02-12 22:28:03

标签: c++ multithreading memory c++11

在他的新书41.2.1 Memory Location部分,B.Stroustrup撰写以下内容:

  

考虑两个全局变量 b c

// thread1
char c = 0;
void f()
{
   c = 1;
   int x = c;
} 

// thread2
char b = 0;
void g()
{
   b = 1;
   int y = b;
}
     

现在,x == 1和y == 1,正如任何人所期望的那样。为什么这甚至值得说?考虑如果分配链接器可能会发生什么   内存中同一个字中的 c b (与大多数现代硬件一样),机器无法加载或存储小于a的任何内容   字:

     

enter image description here

     

如果没有定义明确且合理的内存模型,线程1可能会   阅读包含 b c 的字词,更改 c ,然后编写   回到记忆中的话。同时线程2可以做同样的事情    b 。然后,无论哪个线程设法首先读取该单词   wichever线程设法将其结果写回到内存中   会决定结果。我们可能 10 01 11   (但不是 00 )。记忆模型使我们免于混乱;我们得到   的 11 即可。 00 不能发生的原因是 b c 的初始化(由编译器或链接器完成)之前   要么线程开始。

假设短语:

  

我们可能 10 01 11 (但不是 00

分别指变量 x y 的最终值,我们怎么能得到 10 01 没有合理的记忆模型。我只是看不出这是怎么可能的。

我也无法理解作者在写上述最后一句话时的意思:

  

00 不能发生的原因是初始化   在任一线程启动之前(由编译器或链接器完成) b c

1 个答案:

答案 0 :(得分:5)

在没有合理内存模型的情况下可以获得01或10的原因是因为线程操作同时发生并且内存的读写不是原子的。它们需要两个步骤 - 步骤1:读取,步骤2:写入。如果没有合理的记忆模型,可能会出现以下情况:

线程1:读取00内存:00

线程2:读取00内存:00

线程1:写入10个内存:10

线程2:写入01记忆:01

结果:01

多线程编程时,多线程访问同一资源的问题很常见。例如,需要访问相同静态成员变量的多个线程。我们防止线程跨越彼此的方式是使用互斥锁和关键部分。但是,在提供的情况下,我们不需要这样做,因为内存模型为我们处理它(是明智的)。

00不可能的原因:在任一线程启动之前,内存初始化为00,因此两个线程都没有跟踪其他线程的操作,并将内存设置为00.