跳转到内容
主菜单
主菜单
移至侧栏
隐藏
导航
首页
最近更改
随机页面
MediaWiki帮助
代码酷
搜索
搜索
中文(中国大陆)
外观
创建账号
登录
个人工具
创建账号
登录
未登录编辑者的页面
了解详情
贡献
讨论
编辑“︁
C++ 内存模型
”︁
页面
讨论
大陆简体
阅读
编辑
编辑源代码
查看历史
工具
工具
移至侧栏
隐藏
操作
阅读
编辑
编辑源代码
查看历史
常规
链入页面
相关更改
特殊页面
页面信息
外观
移至侧栏
隐藏
Admin
(
留言
|
贡献
)
2025年4月28日 (一) 21:26的版本
(Page creation by admin bot)
(差异) ←上一版本 |
已核准修订
(
差异
) |
最后版本
(
差异
) |
下一版本→
(
差异
)
警告:您正在编辑该页面的旧版本。
如果您发布该更改,该版本后的所有更改都会丢失。
您的更改会在有权核准的用户核准后向读者展示。
警告:
您没有登录。如果您进行任何编辑,您的IP地址会公开展示。如果您
登录
或
创建账号
,您的编辑会以您的用户名署名,此外还有其他益处。
反垃圾检查。
不要
加入这个!
{{DISPLAYTITLE:C++内存模型}} [[Category:C++学习路径结构]] [[Category:C++多线程]] == 简介 == '''C++内存模型'''是C++标准中定义的一套规则,用于描述多线程环境下程序如何访问内存。它规定了线程间共享数据的可见性、原子性以及操作顺序,是理解多线程编程中数据竞争、同步机制(如互斥锁、原子操作)的基础。C++11首次正式引入内存模型,解决了此前标准中多线程行为的未定义问题。 内存模型的核心目标是: * 定义哪些操作是'''原子的'''(不可分割)。 * 规定线程间数据修改的'''可见性'''(何时对其他线程可见)。 * 控制指令的'''执行顺序'''(编译器/CPU优化的限制)。 == 关键概念 == === 内存顺序(Memory Order) === C++提供了6种内存顺序,定义在<code>std::memory_order</code>枚举中,用于控制原子操作的同步行为: {| class="wikitable" ! 内存顺序 !! 描述 |- | <code>memory_order_relaxed</code> || 无同步要求,仅保证原子性。 |- | <code>memory_order_consume</code> || 依赖该原子变量的后续操作必须在其后执行(罕见使用)。 |- | <code>memory_order_acquire</code> || 当前线程中后续的读操作必须在该原子操作之后执行。 |- | <code>memory_order_release</code> || 当前线程中之前的写操作必须在该原子操作之前完成。 |- | <code>memory_order_acq_rel</code> || 结合acquire和release,适用于读-改-写操作。 |- | <code>memory_order_seq_cst</code> || 默认顺序,保证全局一致性(最强约束)。 |} === 原子操作 === 原子操作是不可中断的操作,通常通过<code>std::atomic</code>类型实现。以下示例展示原子变量的使用: <syntaxhighlight lang="cpp"> #include <atomic> #include <thread> #include <iostream> std::atomic<int> counter(0); void increment() { for (int i = 0; i < 1000; ++i) { counter.fetch_add(1, std::memory_order_relaxed); // 原子递增 } } int main() { std::thread t1(increment); std::thread t2(increment); t1.join(); t2.join(); std::cout << "Counter: " << counter << std::endl; // 输出2000 } </syntaxhighlight> === 数据竞争与同步 === 未正确同步的共享数据访问会导致'''数据竞争'''(Data Race),引发未定义行为。例如: <syntaxhighlight lang="cpp"> int unsafe_counter = 0; void unsafe_increment() { for (int i = 0; i < 1000; ++i) { ++unsafe_counter; // 非原子操作,可能丢失更新 } } </syntaxhighlight> == 内存模型的实际应用 == === 案例1:自旋锁实现 === 利用<code>std::atomic_flag</code>和<code>memory_order_acquire/release</code>实现高效自旋锁: <syntaxhighlight lang="cpp"> #include <atomic> class SpinLock { std::atomic_flag flag = ATOMIC_FLAG_INIT; public: void lock() { while (flag.test_and_set(std::memory_order_acquire)); // 获取锁 } void unlock() { flag.clear(std::memory_order_release); // 释放锁 } }; </syntaxhighlight> === 案例2:单例模式的双重检查锁 === 避免不必要的锁竞争,同时保证线程安全: <syntaxhighlight lang="cpp"> #include <atomic> #include <mutex> class Singleton { static std::atomic<Singleton*> instance; static std::mutex mtx; Singleton() {} public: static Singleton* getInstance() { Singleton* tmp = instance.load(std::memory_order_acquire); if (tmp == nullptr) { std::lock_guard<std::mutex> lock(mtx); tmp = instance.load(std::memory_order_relaxed); if (tmp == nullptr) { tmp = new Singleton(); instance.store(tmp, std::memory_order_release); } } return tmp; } }; </syntaxhighlight> == 内存顺序的可视化 == 以下Mermaid图展示不同内存顺序的约束关系: <mermaid> graph LR A[Thread 1: Store X] -->|Release| B[X可见性] B -->|Acquire| C[Thread 2: Load X] D[Relaxed Store] -.-> E[其他线程可能延迟看到] </mermaid> == 数学表达 == C++内存模型的顺序一致性(Sequential Consistency)可形式化为: <math> \forall \text{操作 } A, B, \quad A \prec B \Rightarrow \text{所有线程观察到 } A \text{在 } B \text{之前} </math> == 总结 == * 使用<code>std::atomic</code>避免数据竞争。 * 根据场景选择合适的内存顺序(例如<code>seq_cst</code>为默认安全选项)。 * 理解“Happens-Before”关系是分析多线程程序的关键。 {{Stub}} ''注:本文仅覆盖基础内容,高级主题如内存屏障(Fence)需进一步学习。'' [[Category:编程语言]] [[Category:C++]] [[Category:C++ 多线程]]
摘要:
请注意,所有对代码酷的贡献均被视为依照知识共享署名-非商业性使用-相同方式共享发表(详情请见
代码酷:著作权
)。如果您不希望您的文字作品被随意编辑和分发传播,请不要在此提交。
您同时也向我们承诺,您提交的内容为您自己所创作,或是复制自公共领域或类似自由来源。
未经许可,请勿提交受著作权保护的作品!
取消
编辑帮助
(在新窗口中打开)
该页面使用的模板:
模板:C++学习路径结构
(
编辑
)