首页 > 后端开发 > C++ > 正文

C++如何使用std::atomic实现无锁编程_C++并发编程与原子操作实践

尼克
发布: 2025-11-13 16:05:07
原创
445人浏览过
std::atomic 提供原子操作以避免数据竞争,相比互斥锁性能更高,适用于高并发场景。通过 memory_order 可控制内存顺序,如 relaxed 用于独立操作,acquire/release 用于同步,seq_cst 保证顺序一致性。compare_exchange_weak 支持无锁数据结构如栈的实现,但需注意 ABA 问题和内存回收。合理使用可提升并发效率,但需谨慎处理复杂性。

c++如何使用std::atomic实现无锁编程_c++并发编程与原子操作实践

在C++并发编程中,std::atomic 是实现无锁(lock-free)操作的核心工具。它保证对共享数据的读写是原子的,避免多个线程同时访问导致的数据竞争和未定义行为。相比互斥锁(mutex),原子操作通常性能更高,尤其适用于高并发、低争用的场景。

理解 std::atomic 的基本用法

std::atomic 模板类可以包装一个基础类型(如 int、bool、指针等),使其操作具有原子性。最常见的是 std::atomic<int>std::atomic<bool>

例如,实现一个线程安全的计数器:

#include <atomic>
#include <thread>
#include <iostream>
<p>std::atomic<int> counter{0};</p><p><span>立即学习</span>“<a href="https://pan.quark.cn/s/6e7abc4abb9f" style="text-decoration: underline !important; color: blue; font-weight: bolder;" rel="nofollow" target="_blank">C++免费学习笔记(深入)</a>”;</p><p>void increment() {
for (int i = 0; i < 1000; ++i) {
counter.fetch_add(1, std::memory_order_relaxed);
}
}</p><p>int main() {
std::thread t1(increment);
std::thread t2(increment);</p><pre class='brush:php;toolbar:false;'>t1.join();
t2.join();

std::cout << "Counter: " << counter.load() << "\n";
return 0;
登录后复制

}

这里使用 fetch_add 原子地增加计数器值,确保不会出现竞态条件。

内存顺序(Memory Order)的选择

原子操作的性能和语义受内存顺序影响。C++ 提供了多种 std::memory_order 枚举值:

豆包AI编程
豆包AI编程

豆包推出的AI编程助手

豆包AI编程 483
查看详情 豆包AI编程
  • memory_order_relaxed:仅保证原子性,不提供同步或顺序约束,适合计数器等独立操作。
  • memory_order_acquire:用于读操作,保证之后的读写不会被重排到该操作之前。
  • memory_order_release:用于写操作,保证之前的读写不会被重排到该操作之后。
  • memory_order_acq_rel:结合 acquire 和 release,常用于 compare-exchange 操作。
  • memory_order_seq_cst:默认顺序,提供最严格的顺序一致性,但开销最大。

例如,在实现自旋锁或标志位通知时,使用 acquire/release 可以避免不必要的全局同步开销:

std::atomic<bool> ready{false};
int data = 0;
<p>// 线程1:生产数据
void producer() {
data = 42;
ready.store(true, std::memory_order_release);
}</p><p>// 线程2:消费数据
void consumer() {
while (!ready.load(std::memory_order_acquire)) {
// 自旋等待
}
std::cout << "Data: " << data << "\n";
}</p>
登录后复制

这种模式确保了 data 的写入在 ready 变为 true 之前完成,且消费者能看到正确的 data 值。

使用 compare_exchange_weak 实现无锁结构

无锁编程的核心是利用 compare_exchange_weakcompare_exchange_strong 实现原子更新。这个操作是“比较并交换”(CAS),常用于构建无锁队列、等数据结构。

下面是一个简单的无锁栈实现片段:

template<typename T>
class LockFreeStack {
private:
    struct Node {
        T data;
        Node* next;
        Node(T const& d) : data(d), next(nullptr) {}
    };
    std::atomic<Node*> head{nullptr};
<p>public:
void push(T const& data) {
Node* new_node = new Node(data);
new_node->next = head.load();
while (!head.compare_exchange_weak(new_node->next, new_node)) {
// 如果 head 被其他线程修改,new_node->next 会被更新为当前 head
// 循环继续尝试
}
}</p><pre class='brush:php;toolbar:false;'>bool pop(T& result) {
    Node* old_head = head.load();
    while (old_head && !head.compare_exchange_weak(old_head, old_head->next)) {
        // 更新 old_head 为当前 head,继续尝试
    }
    if (old_head) {
        result = old_head->data;
        delete old_head;
        return true;
    }
    return false;
}
登录后复制

};

注意:真实项目中需考虑 ABA 问题和内存回收(如使用 hazard pointer 或 RCU)。

基本上就这些。合理使用 std::atomic 能写出高效、低延迟的并发代码,但要小心内存顺序和复杂逻辑带来的隐患。无锁编程虽强,但也容易出错,建议在关键路径或性能敏感场景下谨慎使用。

以上就是C++如何使用std::atomic实现无锁编程_C++并发编程与原子操作实践的详细内容,更多请关注php中文网其它相关文章!

编程速学教程(入门课程)
编程速学教程(入门课程)

编程怎么学习?编程怎么入门?编程在哪学?编程怎么学才快?不用担心,这里为大家提供了编程速学教程(入门课程),有需要的小伙伴保存下载就能学习啦!

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号