C++0x 内存模型和原子操作 (std:::atomic memory order等相关资料)

本文探讨了 C++11 中新增的并行编程特性,特别是 std::atomic 的使用及内存模型。文中详细介绍了不同 memory_order 的含义及其与内存屏障的关系,并通过一个示例展示了如何确保操作间的正确顺序。

并行编程的趋势不可阻挡啊,新的c++标准也加入了很多支持。内存模型和 std::atomic 的引入很值得学习吧,看facebook的开源c++库都用了很多c++ 11的特性了。 std::atomic 这些。


网上看到的最详细清楚的解释是,

C++ Concurrency in Action.pdf  一书的第五章

5 The C++ Memory Model and Operations on Atomic Types

对理解 c++ atomic 的memory order很有用处:


这个网页其实也是摘录的书的内容来的,

Memory Ordering for Atomic Operations in C++0x

http://www.developerfusion.com/article/138018/memory-ordering-for-atomic-operations-in


-c0x/


详细解析了 std::atomic 的不同存储模型 ,不同的值与memory order的关系:

有了linux内核的里面内核屏障的概念的话,像下面这样里面比较容易吧。

typedef enum memory_order {

    memory_order_relaxed,   \\ 不指定内存屏障,所以内存操作执行时可能是乱序的。

    memory_order_acquire,   \\ 按照我理解就是插入一个 内存读屏障,保证之前的读操作先一步完成。清空自己cpu上"invalidate queues"  。

    memory_order_release,    \\ 按照我理解就是插入一个 内存写屏障,保证之前的写操作的顺序一定 。清空自己cpu上 的 “ store buffer"


在这之前完成

    memory_order_consume  类似memory_order_acquire,但只对依赖的指定数据起作用。

    memory_order_acq_rel,    \\ 同时插入读写两个屏障。  清空自己cpu上 的 “ store buffer" 和 "invalidate queues"  。

    memory_order_seq_cst    \\\默认的顺序模型。根据  http://en.cppreference.com/w/cpp/atomic/memory_order 这里的说明 (Total sequential ordering requires a full memory fence CPU instruction on all multi-core systems. This may become a performance bottleneck since it forces all memory accesses to propagate to every thread.)  这个会清空所有cpu上的读写同步消息队列 “ store buffer" 和 "invalidate queues"   (参考 http://hi.baidu.com/widebright/item/4e458d447c8bcfe11381daf0 ) 。  memory_order_acq_rel 应该是只清空自己cpu上 的 “ store buffer" 和 "invalidate queues"  。

        这个看上去和x86的lock指令前缀锁总线不太一样。不知道具体怎么实现的。

 

} memory_order;



书上的一个简单的例子。

-----------------------------------------------

#include <atomic>

#include <thread>

#include <assert.h>

 

std::atomic<bool> x,y;

std::atomic<int> z;

 

void write_x_then_y()

{

    x.store(true,std::memory_order_relaxed);             #1

    y.store(true,std::memory_order_release);             #2   //保证 第#1句的x写入在y的写入之前

}

 

void read_y_then_x()

{

    while(!y.load(std::memory_order_acquire));           #3     //保证 y的读取在 第#4句x的读取之前。所以  如果y看到修改后的值,肯定 第#4句看到的也是x的新的值了。

    if(x.load(std::memory_order_relaxed))                #4

        ++z;

}

 

int main()

{

    x=false;

    y=false;

    z=0;

    std::thread a(write_x_then_y);

    std::thread b(read_y_then_x);

    a.join();

    b.join();

    assert(z.load()!=0);                                 #5    //这个肯定通过的了。

}

-----------------------------------------------------------



也说道了内存屏障了

memory fences/barriers

c++ 里面除了上面那些为atomic类型指定明确的存储模型之外,也可以插入 指定的“内存读写屏障 


”的。



书中的其他章节也挺不粗哦的,

7

Designing Data Structures for

Concurrency II: Lock-free

Concurrent Data Structures



相面这个应该是c++的规范文档,解释了为什么要把c++的内存模型定义成这样子。

C++ Atomic Types and Operations

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2427.html#DiscussOrder

Memory Model Rationales

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2176.html



想std:atomic 等特性,应该在行的gcc 和 vc11 里面都有支持了,

C++11 Features in Visual C++ 11

http://blogs.msdn.com/b/vcblog/archive/2011/09/12/10209291.aspx

Status of Experimental C++0x Support in GCC 4.6

http://gcc.gnu.org/gcc-4.6/cxx0x_status.html


像facebook的开源c++库好像这个std::atomic用的很多了,用来实现spinlock 。

可以去参考一下 https://github.com/facebook/folly/tree/master/folly


【转自:http://hi.baidu.com/widebright/item/ee9d66d2be106dba32db904e】

<think>好的,用户要我介绍一下C++内存模型以及相关的参考资料。我需要先回忆一下自己对这个主题的理解,再组织成清晰的中文回答,同时注意LaTeX格式的正确使用。 首先,C++内存模型主要涉及内存布局并发支持。内存布局部分应该包括不同的内存区域,比如栈、堆、全局/静态存储区等。这部分需要详细描述每个区域的作用特点。然后是对象模型,涉及对象在内存中的布局,比如成员变量、虚函数表等。接着是多线程内存模型,尤其是C++11引入的内存顺序原子操作,这部分比较复杂,需要解释内存顺序的不同类型原子操作的作用。 然后,参考资料部分需要列出权威的资料,比如ISO C++标准文档、C++ Primer、Effective系列书籍、cppreference网站等。这些资料要给出具体的章节或者链接,方便用户查阅。 需要注意用户的系统级指令,所有行内数学公式要用$...$,独立公式用$$...$$。例如,在提到地址空间时可能需要用公式表示,比如地址的范围可以用$0x0000$到$0xFFFF$这样的格式。不过C++内存模型更多是概念性的,可能数学公式用的不多,但如果有涉及计算或布局的结构,可能需要适当使用。 接下来需要检查LaTeX语法是否正确,比如变量、术语是否正确使用$符号包裹。例如,提到指针地址时可能需要用$p$,但大部分情况下可能不需要数学公式。不过为了符合用户的要求,可能需要找到合适的地方加入,比如在解释内存地址布局时。 回答结构要清晰,分点介绍,每个部分有子项。例如,内存布局分为栈、堆、全局区等;对象模型分为成员布局、虚函数表等;多线程部分分为原子操作、内存顺序等。每个子项简要说明,帮助用户逐步理解。 需要确保内容真实可靠,比如C++11引入的内存模型是标准的一部分,而不是编译器的扩展。参考资料要权威,避免引用个人博客或者不可靠的来源。 可能还需要考虑用户的需求层次。用户可能是C++开发者,想深入了解内存管理、并发编程中的内存顺序问题,或者是学生准备面试需要这方面的知识。因此,回答需要既有理论又实用,参考资料也要覆盖不同层次的需求。 最后检查是否有遗漏的部分,比如C++内存对齐(alignment)是否属于内存模型的一部分?应该属于对象模型中的内容,需要提到。另外,内存序的几种类型(relaxed, acquire, release, acq_rel, seq_cst)需要简要解释,但不用太深入,避免让用户混淆。 总结,回答的结构大致分为: 1. C++内存模型概述 2. 内存布局分点介绍 3. 对象模型 4. 多线程内存模型 5. 参考资料 每个部分用清晰的标题子项,使用中文,正确应用LaTeX格式(如果需要的话),并确保参考资料权威且相关。</think>以下是对C++内存模型的详细介绍,结合系统级实现与开发者视角: $$ \boxed{\text{C++内存模型核心:管理对象存储周期与多线程交互规则}} $$ --- ### 一、内存布局模型 1. **栈内存区** - 存储局部变量、函数参数、返回值地址(通过$esp$/$rsp$寄存器管理) - 自动分配/释放,严格遵循LIFO顺序 - 示例:`int x = 10;`($x$存储在栈顶) 2. **堆内存区** - 手动通过`new`/`delete`管理(Linux通过$brk$/$mmap$系统调用扩展) - 碎片化风险,需注意内存泄漏 - 示例:`int* p = new int(20);`($p$指向堆地址) 3. **全局/静态存储区** - 包含全局变量、静态变量(`.data`段初始化,`.bss`段未初始化) - 生命周期贯穿程序始终 - 示例:`static int s_count = 0;` 4. **常量区** - 存储字符串字面量`constexpr`变量(位于`.rodata`段) - 只读属性,修改触发段错误 - 示例:`const char* str = "Hello";` 5. **代码区** - 存储编译后的机器指令(`.text`段) - 具有执行权限,通常只读 --- ### 二、对象内存模型 1. **成员布局规则** - 按声明顺序排列(受访问修饰符影响) - 内存对齐遵循$alignof(T)$规则(可通过`alignas`修改) - 示例: ```cpp struct Foo { char a; // 偏移0 int b; // 偏移4(假设4字节对齐) double c; // 偏移8 }; ``` 2. **虚函数表(vtable)** - 多态类型首部包含$vptr$指向vtable - vtable存储RTTI虚函数地址(编译器隐式生成) - 内存布局示例: ``` +---------+ | vptr | -> 指向Foo的vtable +---------+ | 成员变量 | +---------+ ``` --- ### 三、多线程内存模型C++11起) 1. **原子操作** - 通过`std::atomic<T>`保证操作的不可分割性 - 示例:`atomic<int> counter(0);` 2. **内存顺序(Memory Order)** - 控制指令重排与可见性,6种模式: ```cpp memory_order_relaxed // 无同步 memory_order_acquire // 加载屏障 memory_order_release // 存储屏障 memory_order_acq_rel // 加载+存储屏障 memory_order_seq_cst // 顺序一致性(默认) memory_order_consume // (已弃用) ``` - 典型用例: ```cpp // 线程1 data = ...; flag.store(true, std::memory_order_release); // 线程2 if (flag.load(std::memory_order_acquire)) { // 保证看到线程1的data写入 } ``` 3. **Happens-Before规则** - 定义跨线程操作可见性顺序 - 通过原子操作、互斥锁等建立关系 --- ### 四、关键参考资料 1. **标准文档** - ISO C++ Standard §6.8.1 (内存模型) - §31.4 (原子操作) 2. **书籍** - *C++ Concurrency in Action* (Anthony Williams) - 第5章详解内存模型 - *Effective Modern C++* (Scott Meyers) - Item 40-41 - *C++ Primer* (5th Ed.) - 第12章动态内存 3. **在线资源** - [cppreference.com - Memory model](https://en.cppreference.com/w/cpp/language/memory_model) - [GCC Wiki - Atomic/GCCMM](https://gcc.gnu.org/wiki/Atomic/GCCMM) - [LLVM Memory Model Guide](https://llvm.org/docs/Atomics.html) 4. **论文** - *A Formal Specification of the x86 Memory Model* (Intel, 2009) - *Threads Cannot be Implemented as a Library* (Boehm, 2005) --- 通过理解内存模型,开发者可写出高效且线程安全的代码,尤其在无锁编程性能优化场景中至关重要。建议通过实际调试工具(如Valgrind、TSan)验证内存行为。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值