C++ 需要帮助理解从B.Stroustrup';s的新书

C++ 需要帮助理解从B.Stroustrup';s的新书,c++,multithreading,memory,c++11,C++,Multithreading,Memory,C++11,B.Stroustrup在其新书的第41.2.1节“内存位置”中写道: 考虑两个全局变量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在内存中的同一个单词中,并且(像大多数现代硬件一样)

B.Stroustrup在其新书的第41.2.1节“内存位置”中写道:

考虑两个全局变量bc

// 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,正如大家所预料的那样。这为什么值得一提呢?考虑如果链接器分配会发生什么 cb在内存中的同一个单词中,并且(像大多数现代硬件一样),机器无法加载或存储小于a的任何内容 字:

如果没有定义良好且合理的内存模型,线程1可能会 阅读包含bc的单词,更改c,并写出 单词回到记忆中。同时,线程2也可以这样做 使用b。然后,无论哪个线程先读这个单词,然后 最后一个线程设法将其结果写回内存 将决定结果。我们可能得到1001,或11 (但不是00)。记忆模型将我们从这种混乱中解救出来;我们得到 1100无法发生的原因是bc的初始化在 任一线程都会启动

假设该短语:

我们可能得到100111(但不是00

分别指变量xy的最终值,如果没有合理的记忆模型,我们如何得到1001。我只是不明白这怎么可能

我也不明白作者在写上面最后一句话时的意思:

00无法发生的原因是 bc在任一线程启动之前完成(由编译器或链接器)


如果没有合理的内存模型,可以得到01或10,这是因为线程操作同时发生,并且内存的读写不是原子的。它们需要两个步骤——第一步:读取,第二步:写入。如果没有合理的内存模型,则可能出现以下情况:

线程1:读取00内存:00

线程2:读取00内存:00

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

线程2:写入01内存:01

结果:01

多线程编程中常见的问题是多线程访问同一资源。例如,需要访问同一静态成员变量的多个线程。我们防止线程相互践踏的方法是使用互斥体和关键部分。然而,在本文介绍的情况下,我们不需要这样做,因为内存模型为我们处理它(是合理的)


00不可能的原因是:内存在任一线程启动之前被初始化为00,因此两个线程都不会践踏另一个线程所做的事情,并将内存设置为00

螺纹1的读数为
00
。线程2读取
00
。Thread1写入
10
。Thread2写入
01
。Thread1重新读取
01
,并将0保存在
x
中。Thread2重新读取
01
,并将1保存在
y
中。线程不仅在写b,还在内存中写一个字。当线程启动时,它会在设置c之前将整个单词拉入。关于时间线,请参见上面的注释。至于最后一句话:“00不能发生的原因是b和c的初始化(由编译器或链接器)在任一线程启动之前完成。”尝试“编写00(初始化b和c)的过程”在任何线程开始之前都已经完成,所以在线程执行中间的工作中没有00的写入风险。顺便说一下,这完全可能发生在C++ 11内存模型下的位字段。相邻的位字段属于相同的存储位置;对这些字段的并发访问构成了一场数据竞赛,并表现出未定义的行为。@IgorTandetnik你所说的Thread1 reads 00是什么意思?我终于明白了。将军澳群岛(+1)