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

c++如何实现一个双缓冲队列 c++ Double Buffer【并发】

大浩酱_2866

大浩酱_2866

发布时间:2025-12-23 16:05:59

|

843人浏览过

|

来源于php中文网

原创

双缓冲队列通过两个缓冲区(A/B)和原子指针切换实现无锁高并发生产消费:生产者写write_buf,消费者批量取read_buf并触发交换;SPSC下高效,MPMC需CAS或改用环形缓冲区。

c++如何实现一个双缓冲队列 c++ double buffer【并发】

双缓冲队列(Double Buffer Queue)在高并发场景下常用于解耦生产与消费节奏,避免频繁加锁。它的核心思想是:维护两个缓冲区(buffer A 和 buffer B),生产者只往当前写缓冲区追加数据,消费者只从当前读缓冲区取走数据;当写缓冲区满或需切换时,原子地交换读/写缓冲区角色——此时消费者继续处理旧数据,生产者无缝写入新缓冲区。

基本结构设计(无锁 + 原子切换)

不依赖互斥锁实现高效切换,关键靠 std::atomic 控制当前读/写缓冲区指针。两个缓冲区可为 std::vector、std::deque 或定长数组,根据吞吐和内存特性选择。

  • 用 std::atomic<buffer></buffer> 管理 read_buf 和 write_buf 指针,确保切换操作的原子性
  • 生产者调用 push() 时,直接向 write_buf push_back()(无需锁)
  • 消费者调用 try_pop_batch() 时,先尝试取走整个 read_buf 内容,再触发交换
  • 交换动作本身用 compare_exchange_strong 或简单赋值(若仅单写线程+单读线程,可免 CAS)

典型线程安全切换逻辑

假设单生产者单消费者(SPSC),这是双缓冲最常见且最高效的使用模式:

  • 定义两个缓冲区:Buffer buf_a, buf_b;
  • 初始化:write_buf = &buf_a; read_buf = &buf_b;
  • 生产者写满后(或定时),执行:
    Buffer* expected = write_buf;
        write_buf = (write_buf == &buf_a) ? &buf_b : &buf_a;
        // 此时新 write_buf 已就绪,旧 write_buf 成为待消费目标
        // 通知消费者:交换完成,可开始读原 write_buf(即现在的 read_buf)
  • 消费者收到通知后,将原 write_buf 内容整体移入本地处理队列,并把该缓冲区清空复用为下次读目标

支持多生产者/多消费者的注意事项

MPMC 场景下,纯双缓冲需配合额外同步机制,否则存在竞争风险:

C++14
C++14

C++14 对 C++11 的修正与增强版本,适合旧系统维护和较老工具链兼容。

下载

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

  • 多个生产者同时写同一 write_buf 仍需内部加锁(如 std::mutex 保护 push_back)或改用无锁容器(如 boost::lockfree::queue)
  • 缓冲区切换不能仅靠指针赋值,必须用原子 CAS 防止“ABA”或丢失更新,例如:
    Buffer* old = write_buf.load();
        Buffer* desired = (old == &buf_a) ? &buf_b : &buf_a;
        while (!write_buf.compare_exchange_weak(old, desired)) {
            desired = (old == &buf_a) ? &buf_b : &buf_a;
        }
  • 建议在 MP 场景下改用环形缓冲区(ring buffer)+ 生产/消费索引原子变量,比双缓冲更自然;双缓冲更适合“批量写+批量读”的日志聚合、网络包批处理等场景

简易可运行示例(SPSC,std::vector + 原子指针)

以下是一个最小可行双缓冲队列骨架(省略异常处理和内存池优化):

struct DoubleBufferQueue {
    std::vector<int> buf_a, buf_b;
    std::atomic<std::vector<int>*> read_buf{&buf_b};
    std::atomic<std::vector<int>*> write_buf{&buf_a};
<pre class="brush:php;toolbar:false;">void push(int x) {
    write_buf.load()->push_back(x);
}

std::vector<int> pop_all() {
    auto* r = read_buf.load();
    auto data = std::move(*r); // 移出全部内容
    r->clear();                // 复用前清空
    // 原子交换:让当前 write_buf 成为新的 read_buf
    read_buf.store(write_buf.exchange(r));
    return data;
}

};

注意:此版本要求调用 pop_all() 的线程与 push() 线程严格配对(如主线程 push,工作线程定时 pop_all),且不允许多个线程同时 pop。

相关文章

c++速学教程(入门到精通)
c++速学教程(入门到精通)

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

下载

相关标签:

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

热门AI工具

更多
WorkBuddy

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

DeepSeek

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

音述AI
音述AI Hot

一款AI音频处理工具,主要用于音述AI是一个以“用声音述说故事”为核心的 AI 音乐创作与声音分享社区,适合需要提升相关任务效率的用户。

蛙蛙写作

一款AI论文写作工具,主要用于超级AI智能写作助手,适合需要提升相关任务效率的用户。

切问学术

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

豆包大模型

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

SkildArt
SkildArt Hot

SkildArt是一款AI文本写作工具,一站式 AI 视觉创作平台。

二狗PPT
二狗PPT Hot

一款AI演示文稿工具,主要用于专为中式职场打造的AI PPT生成工具,适合需要提升相关任务效率的用户。

PixTV
PixTV Hot

PixTV是一款面向AIGC内容创作的AI视频生成工具。

相关专题

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

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

4208

2025.08.29

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

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

804

2025.10.23

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

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

379

2026.04.23

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

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

4418

2023.08.10

Gradle插件开发入门教程
Gradle插件开发入门教程

本专题介绍Gradle插件开发的基本流程,涵盖插件类编写、自定义任务注册、扩展参数设计和插件应用方法,帮助你理解插件如何组织构建逻辑,减少多个项目之间的重复配置。

120

2026.10.22

Gradle Wrapper配置教程
Gradle Wrapper配置教程

本专题介绍Gradle Wrapper的基本作用,涵盖文件组成、生成方法、版本配置和任务调用,帮助你理解项目如何使用指定的Gradle版本,减少不同开发环境带来的构建差异。

60

2026.10.22

Golangci-lint检查器使用教程
Golangci-lint检查器使用教程

本专题整理Golangci-lint常用Linters的用途与配置方法,覆盖错误处理、无效代码、安全、复杂度、命名和依赖检查,帮助项目合理选规则。

60

2026.10.22

Gradle怎么构建Java项目
Gradle怎么构建Java项目

本专题介绍Gradle Java项目构建方法,涵盖Java插件配置、依赖声明、源码编译、测试执行和打包检查,帮助你理解各阶段的任务关系,逐步完成项目构建。

40

2026.10.22

PHP时间戳漏洞修复教程
PHP时间戳漏洞修复教程

本专题汇总PHP常见时间戳漏洞,包括2038年溢出、时区漂移、时间戳伪造、重放攻击、时间盲注与日志审计失效等,并给出升级64位环境、使用 DateTimeImmutable、统一UTC、严格超时校验、预处理绑定、hash_equals 比对等修复方案,帮助开发者快速排查和加固时间相关代码。

60

2026.10.22

热门下载

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

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C++ Core Guidelines
C++ Core Guidelines

共0课时 | 0人学习

C++ Reference
C++ Reference

共0课时 | 0人学习

C++ 官方标准说明
C++ 官方标准说明

共0课时 | 0人学习

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

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