c++ - 需要帮助理解从 B.Stroustrup 的新书中摘录的这段文字

标签 c++ multithreading memory c++11

在他的新书的 41.2.1 内存位置部分,B.Stroustrup 写道:

Consider two global variables b and c:

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

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

Now, x==1 and y==1, as anyone would expect. Why is this even worth saying? Consider what might happen if a linker allocated c and b in the same word in memory and (like most modern hardware) the machine could not load or store anything smaller than a word:

enter image description here

Without a well-defined and reasonable memory model, thread 1 might read the word containing b and c, change c, and write the word back into memory. At the same time thread 2 could do the same with b. Then, whichever thread managed to read the word first and wichever thread managed to write its result back into memory last would determine the result. We might get 10, 01, or 11 (but not 00). The memory model saves us from such chaos; we get 11. The reason that 00 cannot happen is that the initialization of b and c are done (by the compiler or the linker) before either thread starts.

假设短语:

We might get 10, 01, or 11 (but not 00)

分别指变量xy的最终值,我们如何得到1001 没有合理的内存模型。我只是看不出这怎么可能。

我也看不懂作者写上面最后一句的意思:

The reason that 00 cannot happen is that the initialization of b and c are done (by the compiler or the linker) before either thread starts.

最佳答案

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

线程 1:读取 00 内存:00

线程 2:读取 00 内存:00

线程 1:写入 10 内存:10

线程 2:写入 01 内存:01

结果:01

多线程访问同一个资源的问题在多线程编程中很常见。例如,多个线程需要访问同一个静态成员变量。我们防止线程相互践踏的方法是使用互斥锁和临界区。但是,在出现的情况下,我们不需要这样做,因为内存模型会为我们处理它(这是明智的)。

不可能00的原因:内存在任何一个线程启动前都被初始化为00,所以两个线程都不会践踏另一个线程已经完成的操作,并将内存设置为00。

关于c++ - 需要帮助理解从 B.Stroustrup 的新书中摘录的这段文字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21741217/

相关文章:

c++ - 为什么 stdfax.h 应该是 MFC 应用程序中的第一个包含文件?

c# - 多线程服务,BackgroundWorker vs ThreadPool?

c - malloc()/free() 的对齐限制

c++ - 如何解决 munmap_chunk() : invalid pointer error in C++

iphone - 在 dealloc 中调用 super 是否重要?

c++ while从具有不同数据类型的文件循环

c++ - Windows Server 2012 上的 SNMP Extension Agent 无法连接到它需要数据的端口

c++ - std::pair - 错误:模板参数数量错误

multithreading - Swift - 我如何等待 dispatch_async 完成?

c++ - 长时间锁定互斥锁是否安全?