C++ 需要帮助理解从B.Stroustrup';s的新书
B.Stroustrup在其新书的第41.2.1节“内存位置”中写道: 考虑两个全局变量b和c: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在内存中的同一个单词中,并且(像大多数现代硬件一样)
// 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的任何内容
字:
如果没有定义良好且合理的内存模型,线程1可能会
阅读包含b和c的单词,更改c,并写出
单词回到记忆中。同时,线程2也可以这样做
使用b。然后,无论哪个线程先读这个单词,然后
最后一个线程设法将其结果写回内存
将决定结果。我们可能得到10,01,或11
(但不是00)。记忆模型将我们从这种混乱中解救出来;我们得到
11。00无法发生的原因是b和c的初始化在
任一线程都会启动
假设该短语:
我们可能得到10、01或11(但不是00)
分别指变量x和y的最终值,如果没有合理的记忆模型,我们如何得到10和01。我只是不明白这怎么可能
我也不明白作者在写上面最后一句话时的意思:
00无法发生的原因是
b和c在任一线程启动之前完成(由编译器或链接器)
如果没有合理的内存模型,可以得到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)