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

std::atomic提供无锁线程同步,通过原子操作如load、store、CAS及内存序控制实现高效并发,适用于计数器、等场景,但需注意ABA问题与内存回收风险。

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

在C++11中,std::atomic 提供了一种类型安全的方式来执行原子操作,避免使用互斥锁实现线程同步,从而提升性能。无锁编程(lock-free programming)利用原子操作保证多线程环境下数据的一致性和可见性,适用于高并发场景。

原子操作的基本概念

原子操作是指不可被中断的操作,要么完全执行,要么不执行,不会出现中间状态。在多线程环境中,对共享变量的读写可能引发竞态条件(race condition),传统做法是用互斥锁保护临界区。而使用 std::atomic 可以在不加锁的情况下安全地访问共享数据。

并不是所有类型都支持原子操作,std::atomic 支持如 int、bool、指针等基础类型。例如:

std::atomic counter{0};std::atomic ready{false};std::atomic ptr;

常见原子操作与内存序

std::atomic 支持多种操作,包括 load、store、fetch_add、exchange、compare_exchange_weak/strong 等。这些操作可以配合不同的内存顺序(memory order)来控制同步强度和性能。

立即学习“C++免费学习笔记(深入)”;

常用的内存序包括:

memory_order_relaxed:仅保证原子性,不提供同步或顺序约束memory_order_acquire:用于读操作,确保之后的读写不会被重排到该操作之前memory_order_release:用于写操作,确保之前的读写不会被重排到该操作之后memory_order_acq_rel:结合 acquire 和 releasememory_order_seq_cst:最严格的顺序一致性,默认选项

示例:递增计数器

std::atomic count{0};

void increment() {count.fetch_add(1, std::memory_order_relaxed);}

使用 compare-and-swap 实现无锁结构

最强大的原子操作之一是 compare_exchange_weakcompare_exchange_strong,它们实现了“比较并交换”(CAS)逻辑,是构建无锁数据结构的基础。

典型用法:

std::atomic value{0};

int expected = value.load();while (!value.compare_exchange_weak(expected, expected + 1)) {// 如果 value 不等于 expected,compare_exchange_weak 会把当前值写入 expected// 并返回 false,循环继续尝试}

这段代码实现了无锁的自增操作。即使多个线程同时执行,也能保证最终结果正确。

简单的无锁栈实现

下面是一个基于链表的无锁栈示例,展示如何使用原子指针和 CAS 构建线程安全的数据结构:

templatestruct lock_free_stack {    struct node {        T data;        node* next;        node(T const& d) : data(d), next(nullptr) {}    };
std::atomic head{nullptr};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 会被更新为最新值        // 继续尝试直到成功    }}T pop() {    node* old_head = head.load();    while (old_head && !head.compare_exchange_weak(old_head, old_head->next)) {        // 尝试将 head 指向下一个节点    }    if (old_head) {        T result = old_head->data;        delete old_head;        return result;    }    throw std::runtime_error("empty stack");}

};

注意:这个简单实现存在 ABA 问题和内存回收风险,在生产环境中需结合 hazard pointer 或 epoch-based 回收机制。

基本上就这些。合理使用 std::atomic 能有效减少锁竞争,提高并发性能,但需要仔细处理内存序和异常情况。无锁编程虽高效,但也更复杂,建议在真正需要性能优化时再采用。

以上就是C++如何使用原子操作_C++11 std::atomic实现无锁编程的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1487882.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2025年12月19日 11:04:44
下一篇 2025年12月19日 11:04:53

相关推荐

发表回复

登录后才能评论
关注微信