讲师中心 微信公众号
AI工具推荐 视频效率加速

c++中如何实现一个高性能的无锁队列? (CAS操作详解)

千敏姑娘_7925

千敏姑娘_7925

发布时间:2026-01-14 11:43:15

|

657人浏览过

|

来源于php中文网

原创

直接用 std::atomic 实现无锁队列易出错,主因是MPMC场景下单指针CAS无法保证插入/弹出原子性,且面临ABA问题;安全方案需用带版本号的tagged pointer(如48位指针+16位版本号),要求指针64KB对齐,并严格配对memory_order。

c++中如何实现一个高性能的无锁队列? (cas操作详解)

为什么直接用 std::atomic 实现无锁队列容易出错?

因为无锁队列本质是多生产者多消费者(MPMC)场景,仅靠对 head 或 tail 单个指针做 fetch_add 无法保证节点插入/弹出的原子性。典型错误是「ABA问题」:线程A读到 tail == p,被调度走;线程B把 p 弹出又重用了同一内存地址;线程A回来继续 CAS,误以为链表结构没变,导致指针断裂或重复释放。

真正安全的做法必须同时控制两个指针状态,常见方案是使用双字 CAS(double-word CAS),但 x86-64 的 cmpxchg16b 指令需开启特定编译选项且部分老 CPU 不支持;更通用的解法是引入版本号(tagged pointer)——把指针低几位腾出来存计数,避免 ABA。

std::atomic<uint64_t></uint64_t> 模拟 tagged pointer 的写法

将 64 位整数拆成 48 位指针 + 16 位版本号(足够应对绝大多数场景),所有 CAS 都作用于这个整数。关键点在于:指针必须 64KB 对齐(确保低 16 位为 0),才能安全移位。

  • 分配节点时用 aligned_alloc(65536, sizeof(Node)) 或自定义内存池
  • 读取指针:ptr = (Node*)(val & ~0xFFFFULL)
  • 读取版本:ver = val & 0xFFFFULL
  • CAS 前必须构造新值:new_val = ((uint64_t)new_ptr) | ((old_ver + 1) & 0xFFFFULL)
struct Node {
    int data;
    std::atomic<uint64_t> next; // 存储 tagged pointer
};

struct LockFreeQueue {
    std::atomic<uint64_t> head; // tagged pointer
    std::atomic<uint64_t> tail;

    LockFreeQueue() : head(0), tail(0) {}
};

CAS 循环中必须检查空队列和满队列边界

无锁队列不是“无边界”,而是边界检查必须嵌入 CAS 循环内,否则多个线程可能同时判定“可入队”却争抢同一槽位。例如基于数组的环形无锁队列(如 Dmitry Vyukov 队列),enqueue 中要反复读 tail、计算索引、检查 queue[(tail + 1) % capacity] != nullptr,再尝试 CAS 更新 tail —— 这个检查不能放在 CAS 外部,否则会漏掉其他线程刚写入的值。

MFA WORD
MFA WORD

强制使用密钥词进行 MFA 以访问敏感数据,支持超级密钥词紧急重置。

下载

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

基于链表的实现同样如此:插入前必须确认 tail->next == nullptr,但这个判断本身不是原子的,所以要用 CAS 尝试设置 tail->next = new_node,失败则说明已有其他线程抢先推进了 tail,需重新读取最新 tail。

实际项目中更推荐用成熟实现而非手写

Linux 内核的 lockless list、Facebook 的 Folly::MPMCQueue、Boost.Lockfree,都经过大量压测和内存模型验证。手写无锁结构最易出问题的地方不在 CAS 本身,而在内存序(memory order)选择:std::memory_order_acquire 和 std::memory_order_release 必须成对出现在读/写路径上,漏掉一个就可能导致重排序后看到脏数据;而 std::memory_order_relaxed 在某些路径下看似能提升性能,实则破坏 happens-before 关系。

如果你只是需要高吞吐队列,优先考虑 Folly::MPMCQueue 并启用 cache_line_size 对齐;若必须手写,请用 clang++ -fsanitize=thread 跑压力测试,而不是靠逻辑推演确认正确性。

相关文章

数码产品性能查询
数码产品性能查询

该软件包括了市面上所有手机CPU,手机跑分情况,电脑CPU,电脑产品信息等等,方便需要大家查阅数码产品最新情况,了解产品特性,能够进行对比选择最具性价比的商品。

下载

相关标签:

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

创客贴AI

创客贴AI是一款AI图像与设计工具,AI辅助的智能在线设计工具。

超级麦吉

一款通过数字员工协作完成调研、数据分析与文档制作的AI办公平台。

讯飞绘文

讯飞绘文是一款由科大讯飞推出的一站式 AIGC 内容运营平台。

Loomy
Loomy Hot

一款AI工具,主要用于科大讯飞发布的桌面级 AI 助理,比 OpenClaw 更易用、更安全!,适合需要提升相关任务效率的用户。

切问学术

切问学术是一款AI论文写作工具,复旦大学NLP团队推出的AI学术智能体。

立刻MV
立刻MV Hot

立刻MV是一款AI文本写作工具,AI 音乐视频(MV)创作工具。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

相关专题

更多
c++怎么把double转成int
c++怎么把double转成int

本专题整合了 c++ double相关教程,阅读专题下面的文章了解更多详细内容。

4288

2025.08.29

C++中int、float和double的区别
C++中int、float和double的区别

本专题整合了c++中int和double的区别,阅读专题下面的文章了解更多详细内容。

824

2025.10.23

C++ 智能指针与现代内存管理
C++ 智能指针与现代内存管理

深入讲解 C++ 现代内存管理的核心工具——智能指针,涵盖 unique_ptr 独占所有权语义、shared_ptr 引用计数机制与循环引用问题、weak_ptr 弱引用的应用场景、make_unique/make_shared 工厂函数的性能优势、自定义删除器的编写、RAII 资源管理思想的实践,以及从裸指针迁移到智能指针的重构策略,帮助开发者编写安全无泄漏的现代 C++ 代码。

379

2026.04.23

线程和进程的区别
线程和进程的区别

线程和进程的区别:线程是进程的一部分,用于实现并发和并行操作,而线程共享进程的资源,通信更方便快捷,切换开销较小。本专题为大家提供线程和进程区别相关的各种文章、以及下载和课程。

4498

2023.08.10

Java 并发编程高级实践
Java 并发编程高级实践

本专题深入讲解 Java 在高并发开发中的核心技术,涵盖线程模型、Thread 与 Runnable、Lock 与 synchronized、原子类、并发容器、线程池(Executor 框架)、阻塞队列、并发工具类(CountDownLatch、Semaphore)、以及高并发系统设计中的关键策略。通过实战案例帮助学习者全面掌握构建高性能并发应用的工程能力。

563

2025.12.01

磁盘配额是什么
磁盘配额是什么

磁盘配额是计算机中指定磁盘的储存限制,就是管理员可以为用户所能使用的磁盘空间进行配额限制,每一用户只能使用最大配额范围内的磁盘空间。php中文网为大家提供各种磁盘配额相关的内容,教程,供大家免费下载安装。

4310

2023.06.21

如何安装LINUX
如何安装LINUX

本站专题提供如何安装LINUX的相关教程文章,还有相关的下载、课程,大家可以免费体验。

3633

2023.06.29

linux find
linux find

find是linux命令,它将档案系统内符合 expression 的档案列出来。可以指要档案的名称、类别、时间、大小、权限等不同资讯的组合,只有完全相符的才会被列出来。find根据下列规则判断 path 和 expression,在命令列上第一个 - ( ) , ! 之前的部分为 path,之后的是 expression。还有指DOS 命令 find,Excel 函数 find等。本站专题提供linux find相关教程文章,还有相关

2893

2023.06.30

Vite 项目如何打包和部署
Vite 项目如何打包和部署

Vite项目打包部署专题汇集生产构建、产物预览、输出目录、资源路径、Nginx与GitHub Pages部署及常见白屏和路由404问题的已审核文章,帮助读者完成上线流程。

60

2026.10.28

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Python uv官方安装与入门文档
Python uv官方安装与入门文档

共0课时 | 0人学习

Buffalo框架快速入门指南
Buffalo框架快速入门指南

共0课时 | 0人学习

Valgrind支持平台说明
Valgrind支持平台说明

共0课时 | 0人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn