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。

海康VisionMaster表面缺陷滤波实战:从参数调优到工业检测避坑指南

本文深入探讨海康VisionMaster表面缺陷滤波技术在工业检测中的应用,从参数调优到ROI绘制与Blob分析的协同策略,提供金属外壳、锂电池铝壳等复杂表面的缺陷检测实战指南。通过多级滤波架构和动态ROI生成法,显著提升检出率至98.7%,误检率低于0.5%,为工业质检提供智能化解决方案。

ujm5678901的博客 330

微信H5网页授权通用方案:中转页破解域名限制,适配Hash/History路由

在Web开发中,OAuth 2.0授权码模式是实现第三方登录的通用标准,其核心原理是通过授权服务器颁发临时代码,再由客户端交换访问令牌。这一机制在微信公众号H5开发中尤为重要,用于安全获取用户身份。然而,微信平台对网页授权回调域名有严格的数量限制,这成为多子域名、多环境及微前端架构下业务扩展的主要瓶颈。其技术价值在于通过设计一个统一的中转授权页,将授权逻辑与业务逻辑解耦,让所有业务页面共享一个已配置的授权入口,从而突破域名配额限制。该方案的关键在于适配不同的前端路由模式,需精准处理Hash模式与Histor

weixin_42533120的博客 318

知识图谱初步学习(一)——本体+Protege新手学习

文章目录前言(本体详解)1.本体概念2.本体分类3.本体组成4.本体构建方法一、protege简介二、软件使用步骤1.安装2.使用三、问题解决方案汇总 前言(本体详解) 在开始学习知识图谱的过程中,首先就是要了解什么是本体(ontology)。 1.本体概念 本体的概念最初源自于哲学领域,在哲学中的定义为“对世界上客观事物的系统描述,即存在论”。哲学中的本体关心的是客观现实的抽象本质。而在计算机领域,本体是可以在语义的层次上来对知识进行描述,可以看做是某一个领域知识的通用模型。 本体是从客观世界中抽象出来

qq_43654669的博客 3万+

海康视觉相机驱动软件MVS参数配置全攻略(附接线图+避坑指南)

本文提供了海康视觉相机驱动软件MVS从硬件连接到软件参数配置的完整指南。详细解析了供电与通讯线缆的区分、PNP/NPN信号逻辑的接线避坑方法,并重点阐述了MVS软件中触发模式、网络IP配置、图像采集及光源控制等核心参数的设置技巧,旨在帮助用户快速完成相机调试,实现稳定高效的图像采集。

weixin_29204205的博客 401

【Gazebo安装指南】Ubuntu22.04LTS环境下的高效配置与常见问题解决

本文提供了在Ubuntu 22.04 LTS系统上高效安装和配置Gazebo仿真环境的详细指南。针对Gazebo Classic版本,文章对比了通过ROS 2仓库和Ubuntu官方仓库两种主流安装方法,并重点解决了安装过程中常见的软件包定位、模型下载及图形驱动等问题,帮助用户快速搭建稳定的机器人仿真开发环境。

weixin_29279101的博客 437

JLink 添加国产芯片手把手教程(雅特力 + 华大)

拷贝厂商算法文件夹 + 配置 JLinkDevices.xml。雅特力直接复制官方配置,华大按需添加芯片节点,操作一次,永久生效,以后调试 AT32、HC32 再也不用愁找不到型号。这套方法适配全版本 JLink,也是国产 MCU 替代项目的必备技能,看完照着做,新手也能轻松搞定。百度网盘资料分享:通过网盘分享的文件:jink驱动(包括新增芯片型号)链接: https://pan.baidu.com/s/14SLgrPfyof1lglD6VQguAw?pwd=cfuq 提取码: cfuq。

weixin_48867130的博客 713

(七)独立按键

(七)独立按键

m0_52555663的博客 1720

Python爬虫:爬取拼多多平台商品信息、销量、价格等数据

在本篇博客中,我们将深入探讨如何使用Python爬虫技术爬取拼多多平台的商品信息,包括商品的标题、销量、价格等详细数据。拼多多的商品页面通常是分页展示的,因此我们需要遍历多个页面,获取所有商品的信息。每个商品在拼多多平台上都有一个唯一的商品ID,我们可以通过该ID访问商品页面。通过以上的技术方案和代码示例,你已经掌握了如何使用Python爬虫获取拼多多平台上的商品信息、销量、价格等数据。等技术,解决拼多多平台的反爬虫机制,成功抓取我们所需的商品数据。,我们能够应对拼多多的反爬虫机制,稳定地获取到商品数据。

2201_76125261的博客 3657

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

上一篇: 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、付费专栏及课程。

余额充值