spdlog-mpmc_bounded_q.h 无锁队列源码分析

无锁队列之Mpmc索引队列 这条语句后被长时间中断,导致其它生产者线程不断pop,消费者线程在使用完这些pop出来的索引值后重新归还给Mpmc索引队列,索引队列中存储的索引最终产生数据溢出,索引值被重置为一个较小值,此后线程A恢复执行value = loadvalueAt(readPosition, std::memory_order_relaxed);如果从Mpmc索引队列A pop出一个索引后,需要将该索引push进另外一个Mpmc队列B缓存,通过两个索引队列的协作可以产生索引先进先出,谁先pop出队列A,谁就先得到使用的功能。 阅读详情

spdlog–mpmc_bounded_q.h 无锁队列分析

spdlog中调用了mpmc_bounded_q.h无锁队列实现异步写日志。

构造函数

构造函数传入buffer最大值,并初始化了buffer数组buffer_以及buffer_mask_。

  • buffer_size必须是2的幂次方。
  • 设置每个buffer[i]的值为其序号。
  • 设置入队、出队位置为0。
    mpmc_bounded_queue(size_t buffer_size)
        :max_size_(buffer_size),
         buffer_(new cell_t [buffer_size]),
         buffer_mask_(buffer_size - 1)
    {
        //queue size must be power of two
        if(!((buffer_size >= 2) && ((buffer_size & (buffer_size - 1)) == 0)))
            throw spdlog_ex("async logger queue size must be power of two");

        for (size_t i = 0; i != buffer_size; i += 1)
            buffer_[i].sequence_.store(i, std::memory_order_relaxed);
        enqueue_pos_.store(0, std::memory_order_relaxed);
        dequeue_pos_.store(0, std::memory_order_relaxed);
    }

入队函数 bool enqueue(T&& data)

  1. 获取插入的位置pos = enqueue_pos_
  2. 获取pos处的buffer_, 即cell_
  3. 判断pos是否等于cell_->sequence_
  4. 若相等,尝试占领pos这个位置(enqueue_pos_.compare_exchange_weak),让enqueue_pos_加一,跳出循环
  5. 若cell_->sequence_ < pos, 队列中保存的数据已达到max_size_,不入队
  6. 若cell_->sequence_ > pos,说明cell_处已经被写入数据,更新pos,重新进入第2步

疑问

cell->sequence_.store(pos + 1, std::memory_order_release);,这里困扰我一阵,为什么要将cell的sequence设为pos+1?

个人见解

我觉得主要作用是标记pos处已经放置数据了。若其他线程获得相同的pos,当其再比较pos和sequence时将不会再相等,就不会再次在相同的pos处写入数据。另外,此处的pos+1和出队时的判断intptr_t dif = (intptr_t)seq - (intptr_t)(pos + 1);相对应。

    bool enqueue(T&& data) // 传入待插入数据的右值引用
    {
        cell_t* cell;
        size_t pos = enqueue_pos_.load(std::memory_order_relaxed); // 获取插入的位置
        for (;;)  //一直循环,直到enqueue_pos_.compare_exchange_weak返回true
        {
            cell = &buffer_[pos & buffer_mask_];  // 取出一个buffer_
            size_t seq = cell->sequence_.load(std::memory_order_acquire); // 取出buffer_自己的序号
            intptr_t dif = (intptr_t)seq - (intptr_t)pos;
            if (dif == 0) // 如果是
一个Wait-Free MPMC队列的实现 知乎原文:一个Wait-Free MPMC队列的实现 昨天在wait-free是指什么的评论中,我和朱元兄对wait-free的MPMC(多生产者多消费者)队列进行了一番探讨,也激发了我对已有的wait-free思路进行更深入的挖掘,结果发现MPMC队列有可能做到完全wait-free。于是,本着"shut up and show me the code"的原则,我尝试实现了一个MPMC队列,经过... 阅读详情

相关推荐

spdlog-master.rar_mpmc_bounded_q.h_spdlog

spdlog 是一个快速的 C++ 日志库,只包含头文件,兼容 C++11。

[官方培训]22-UE资产优化 Epic 肖月 笔记

Nanite+Lumen目标:面向TA,美术,不影响视觉的前提下,优化运行和编辑效率引擎:UE5.1延迟管线平台:主流PC,Windows 10 with DX12。

Tcohneyn的博客 1576

别再为镜面物体检测发愁了!手把手教你用PMD相位偏折术增强2.5D形状图细节(附Python代码)

本文详细解析了PMD相位偏折术在工业视觉中镜面物体检测的应用,通过2.5D成像方案增强形状图细节。文章提供了Python代码示例,介绍了一种计算高效的局部特征增强算法,帮助解决产线环境中的噪声问题,提升缺陷识别准确率。

weixin_29299807的博客 346

【论文精度】生成式预训练模型——BART(Bidirectional and Auto-Regressive Transformers)

​ BART是一个预训练的seq2seq的去噪自编码(denoising autoencoder)模型,BART以下方式进行训练①用任意的噪声函数(noising function)去破坏文本;②学习一个模型来重建原始文本。它使用一个标准的基于transformer的神经机器翻译架构,可以看作是BERT(双向编码器)、GPT(left-to-right解码器)以及其他预训练方案的推广。

weixin_45828972的博客 7450

2024年【MCM/ICM】美国大学生数学建模竞赛优秀论文(免费下载)

美国大学生数学建模竞赛(MCM/ICM)由美国数学及其应用联合会主办,是最高的国际性数学建模竞赛,也是世界范围内最具影响力的数学建模竞赛,一般也指数学建模竞赛。赛题内容涉及经济、管理、环境、资源、生态、医学、安全、等众多领域。竞赛要求三人(本科生和研究生均可参加)为一组,在四天时间内,就指定的问题完成从建立模型、求解、验证到论文撰写的全部工作,体现了参赛选手研究问题、解决方案的能力及团队合作精神。为现今各类数学建模竞赛之鼻祖。

weixin_43608857的博客 1841

第一节:从Chat_Bot 到 AI_Agent——一个范式转换

本文系统剖析了工业级AI代理系统ClaudeCode的设计原理与工程实践。通过对比ChatBot与Agent的三个本质差异:自主循环决策vs单轮应答、环境交互vs纯文本I/O、持久状态管理vs无状态对话,揭示了构建生产级Agent系统的关键挑战。文章详细解析了ClaudeCode的五层架构设计、1800+文件组成的运行时系统,包括工具调度、权限管理、状态持久化等核心机制,并阐述了从简单API调用到完整Agent系统的演进路径。

2201_75869398的博客 68

音频链路分析

音频链路分析摘要 本文分析了蓝牙音频设备(BES2700)的音频传输链路,主要包括通话和音乐播放两种场景: 通话链路: 下行:蓝牙接收数据→解码→通过Codec输出到扬声器 上行:麦克风采集→Codec处理→蓝牙编码发送 音乐播放链路: 通过A2DP协议接收高质量音频数据 经过解码、EQ调节等音频处理后输出 系统采用多线程消息机制处理音频任务,通过mailbox传递控制消息,由回调函数处理具体音频数据流。不同应用场景使用不同的蓝牙协议栈(HFP/HSP用于通话,A2DP用于媒体)和编码方式(mSBC/SBC

云淡风轻 85

NXP(恩智浦)—TJA1043TK CAN收发器芯片详解

本文章主要讲解NXP(恩智浦)—TJA1043TK CAN收发器的相关知识。

零零刷的博客 2201

Autosar MCAL-S32K324 Fls配置-基于EB

Autosar MCAL Flash配置,基于S32K324,EB软件

赞的博客 1516

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

上一篇: c++ 文件读取函数总结
下一篇: LeetCode Weekly Contest 82: Goat Latin
Subly
博客等级 码龄14年 10粉丝 17原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值