无锁队列--知识分享
目录
无锁队列
无锁队列是什么
为什么需要无锁队列
队列的类型
无锁队列的分类
ringbuffer(SPSC)
ret_ring(MPMC)
无锁队列
无锁队列是什么
- 无锁队列通过原子操作来实现线程安全的队列,属于非阻塞队列
- 有锁队列通过互斥锁或其他同步机制保证线程安全的队列,属于阻塞队列
为什么需要无锁队列
锁的局限:
- 线程阻塞带来的切换
- 死锁风险
- 性能瓶颈,高并发下锁竞争激烈,吞吐量下降
队列的类型
无锁队列
- 无锁(lock-free):保证了至少有一个线程在正常运行,其他可能重试,依赖CAS 等原子操作。
- 无等待(wait-free):所有线程必成功,无重试,依赖exchange等原子操作。
有锁队列
- 阻塞队列(blocking-queue):当队列为空时,从队列中获取元素的操作会被阻塞,直到队列中有新的元素加入;当队列已满时,向队列中添加元素的操作会被阻塞,直到队列中有元素被移除,依赖锁实现。
无锁队列的分类
SPSC(单生产者,单消费者)
含义:单生产者单消费者队列,即队列只有一个生产者线程和一个消费者线程。
特点:不存在多个生产者或消费者之间的竞争,所以可以使用比较简单高效的算法来实现。
MPSC(多生产者,单消费者)
含义:多生产者单消费者队列,多个线程可以同时向队列中添加元素,但只有一个线程可以从队列中取出元素。
特点:实现时需要重点处理多个生产者之间的并发问题,确保多个生产者能够安全地向队列中添加元素。而对于消费者线程,由于是唯一的,处理相对简单。
SPMC(单生产者,多消费者)
含义:单生产者多消费者队列,只有一个线程可以向队列中添加元素,但是有多个线程可以同时从队列中取出元素。
特点:需要处理多个消费者之间的并发问题,保证多个消费者能够安全地从队列中取出元素。同时,要确保生产者在添加元素时不会受到消费者的干扰。
MPMC(多生产者,多消费者)
含义:多生产者多消费者队列,意味着有多个线程可以同时向队列中添加元素(生产者),也有多个线程可以同时从队列中取出元素(消费者)。
特点:由于多个生产者和消费者可能会同时访问队列,因此需要更复杂的并发控制机制来保证线程安全。通常会使用 CAS 等原子操作来处理多个线程对队列的并发访问,避免数据竞争和不一致的问题。
ringbuffer(SPSC)
#pragma once// SPSC
#include <atomic>
#include <cstddef>
#include <type_traits>template<typename T, std::size_t Capacity>
class RingBuffer
{
public:static_assert(Capacity && !(Capacity & (Capacity - 1)), "Capacity must be power of 2");RingBuffer() : read_(0), write_(0) {}~RingBuffer() {std::size_t r = read_.load(std::memory_order_relaxed);std::size_t w = write_.load(std::memory_order_relaxed);while (r != w) {reinterpret_cast<T *>(&buffer_[r])->~T();r = (r + 1) & (Capacity - 1);}}// 这里使用万能引用和完美转发,支持左值和右值template<typename U>bool Push(U && value) {const std::size_t w = write_.load(std::memory_order_relaxed);const std::size_t next_w = (w + 1) & (Capacity - 1);// 检查缓冲区是否满if (next_w == read_.load(std::memory_order_acquire)) {return false;}new (&buffer_[w]) T(std::forward<U>(value));write_.store(next_w, std::memory_order_release);return true;}bool Pop(T & value) {const std::size_t r = read_.load(std::memory_order_relaxed);// 检查缓冲区是否空if (r == write_.load(std::memory_order_acquire)) {return false;}// 取出元素并析构value = std::move(*reinterpret_cast<T *>(&buffer_[r]));reinterpret_cast<T *>(&buffer_[r])->~T();read_.store((r + 1) & (Capacity - 1), std::memory_order_release);return true;}std::size_t Size() const {const std::size_t r = read_.load(std::memory_order_acquire);const std::size_t w = write_.load(std::memory_order_acquire);return (w >= r) ? (w - r) : (Capacity - r + w);}private:
//cache line 64Balignas(64) std::atomic<std::size_t> read_;alignas(64) std::atomic<std::size_t> write_;alignas(64) std::aligned_storage_t<sizeof(T), alignof(T)> buffer_[Capacity]; // 支持 pod 和 非 pod 类型
};
ret_ring(MPMC)
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>#include "rte_ring.h"#define RING_SIZE 16<<20typedef struct cc_queue_node {int data;
} cc_queue_node_t;static struct rte_ring *r;typedef unsigned long long ticks;static __inline__ ticks getticks(void)
{u_int32_t a, d;asm volatile("rdtsc" : "=a" (a), "=d" (d));return (((ticks)a) | (((ticks)d) << 32));
}void *enqueue_fun(void *data)
{int n = (int)data;int i = 0;int ret;cc_queue_node_t *p;for (; i < n; i++) {p = (cc_queue_node_t *)malloc(sizeof(cc_queue_node_t));p->data = i;ret = rte_ring_mp_enqueue(r, p);if (ret != 0) {printf("enqueue failed: %d\n", i);}}return NULL;
}void *dequeue_func(void *data)
{int ret;int i = 0;int sum = 0;int n = (int)data;cc_queue_node_t *p;ticks t1, t2, diff;//return;t1 = getticks();while (1) {p = NULL;ret = rte_ring_sc_dequeue(r, (void **)&p);if (ret != 0) {//do something}if (p != NULL) {i++;sum += p->data;free(p);if (i == n) {break;}}}t2 = getticks();diff = t2 - t1;printf("time diff: %llu\n", diff);printf("dequeue total: %d, sum: %d\n", i, sum);return NULL;
}int main(int argc, char *argv[])
{int ret = 0;pthread_t pid1, pid2, pid3, pid4, pid5, pid6;pthread_attr_t pthread_attr;r = rte_ring_create("test", RING_SIZE, 0);if (r == NULL) {return -1;}printf("start enqueue, 5 producer threads, echo thread enqueue 1000 numbers.\n");pthread_attr_init(&pthread_attr);if ((ret = pthread_create(&pid1, &pthread_attr, enqueue_fun, (void *)1000)) == 0) {pthread_detach(pid1);}if ((ret = pthread_create(&pid2, &pthread_attr, enqueue_fun, (void *)1000)) == 0) {pthread_detach(pid2);}if ((ret = pthread_create(&pid3, &pthread_attr, enqueue_fun, (void *)1000)) == 0) {pthread_detach(pid3);}if ((ret = pthread_create(&pid4, &pthread_attr, enqueue_fun, (void *)1000)) == 0) {pthread_detach(pid4);}if ((ret = pthread_create(&pid5, &pthread_attr, enqueue_fun, (void *)1000)) == 0) {pthread_detach(pid5);}printf("start dequeue, 1 consumer thread.\n");if ((ret = pthread_create(&pid6, &pthread_attr, dequeue_func, (void *)5000)) == 0) {//pthread_detach(pid6);}pthread_join(pid6, NULL);rte_ring_free(r);return 0;
}
相关文章:
无锁队列--知识分享
目录 无锁队列 无锁队列是什么 为什么需要无锁队列 队列的类型 无锁队列的分类 ringbuffer(SPSC) ret_ring(MPMC) 无锁队列 无锁队列是什么 无锁队列通过原子操作来实现线程安全的队列,属于非阻塞队列 …...
Flask快速入门
1.安装 Flask 要使用 Flask,你需要先安装它。打开终端,运行以下命令: pip install flask 2.创建文件结构 3.app.py from flask import Flask:从 flask 库中导入 Flask 类。app Flask(__name__):创建一个 Flask 应…...
LeetCode -- Flora -- edit 2025-04-16
1.两数之和 1. 两数之和 给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。 你可以假设每种输入只会对应一个答案,并且你不能使用两次相同的元素。 你可以按…...
【Unity笔记】实现可视化配置的Unity按键输入管理器(按下/长按/松开事件 + UnityEvent绑定)
【Unity笔记】实现可视化配置的Unity按键输入管理器 适用于角色控制、技能触发的Unity按键输入系统,支持UnityEvent事件绑定、长按/松开监听与启用开关 一、引言 在 Unity 游戏开发中,处理键盘输入是最常见的交互方式之一。尤其是角色控制、技能释放、菜…...
SpringMVC学习(请求与响应。常见参数类型接收与响应。@RequestParam、@RequestBody的使用)(详细示例)
目录 一、请求与响应。(RequestMapping) (1)使用注解RequestMapping对业务模块区分。 StudentController。 TeacherController。 (2)Apifox请求与响应。 "/student/login"。 "/teacher/login"。 二、常见参数…...
springboot 切面拦截自定义注解
使用切面来拦截被该注解标记的方法 依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId> </dependency>1. 定义自定义注解 import java.lang.annotation.ElementType; imp…...
QT —— 信号和槽(自定义信号和槽函数)
QT —— 信号和槽(自定义信号和槽函数) 自定义信号和槽函数一、自定义信号函数规范1. 声明位置2. 返回值与实现3. 参数与重载 二、自定义槽函数规范1. 声明位置(不同版本差异)2. 返回值与实现3. 参数与重载 三、信号发射规范1. 基…...
朋克编码以潮玩语言讲述中国文化|益民艺术馆展演东方潮力
朋克编码于广州益民艺术馆推出“艺术家潮玩”系列主题展,将传统文化元素融入 潮玩设计,并通过数字科技与空间场景创新,讲述中国故事、传递东方美学。 展览作品结合太空猿等原创 IP 与“中式元素”视觉符号,引发观众情感共鸣。“我…...
TA学习之路——2.2 模型与材质基础
1.模型基础 1.1 图形渲染管线 1.2 模型实现的原理 点连成线,线构成面,面构成模型。 1.2 UV UV例如一个正方体的纸盒展开,平铺在一个二维的坐标系中。 模型的每一个顶点在三维空间和二维空间中都能一 一对应。在二维坐标系中的顶点对应的位置就是顶点的纹理坐标。 因此…...
helm的go模板语法学习
1、helm chart 1.0、什么是helm? 介绍:就是个包管理器。理解为java的maven、linux的yum就好。 安装方法也可参见官网: https://helm.sh/docs/intro/install 通过前面的演示我们知道,有了helm之后应用的安装、升级、查看、停止都…...
Windows 图形显示驱动开发-WDDM 1.2功能—Windows 8 中的 DirectX 功能改进(一)
Windows 8包括 Microsoft DirectX 功能改进,使开发人员、最终用户和系统制造商受益。 功能改进在以下几个方面: 像素格式 (5551、565、4444) :在低功耗硬件配置下,DirectX 应用程序的性能更高。双精度着色器功能:高级…...
软件测试|App测试面试相关问题(2)
一、App 稳定怎么做的?Monkey 怎么用(App 稳定测试)? 稳定性这块,我们当时用的是SDK 自动的一个Monkey 工具进行测试的,其实Monkey工具主要通过模拟用户发送伪随机时间去操作软件,通过执行Monkey 命令,它会自动出报告ÿ…...
模拟电路需要了解的一些基础知识(部分)
基本的单路元件 1. 电阻;特性:阻碍电流流动,消耗电能并转化为热能(遵循欧姆定律)。是无源元件,应用:限流、分压、发热等; 2. 电容;特性:存储电荷和电场能&am…...
[特殊字符] MySQL MCP 开发实战:打造智能数据库操作助手
💡 简介:本文详细介绍如何利用MCP(Model-Control-Panel)框架开发MySQL数据库操作工具,使AI助手能够直接执行数据库操作。 📚 目录 引言MCP框架简介项目架构设计开发环境搭建核心代码实现错误处理策略运行和…...
软考备考(一)学习笔记
一、软考介绍 计算机软考,计算机技术与软件专业技术资格(水平)考试 一年考试两次: 一次上旬(5月底),下旬一次(11月初) 初级资格:程序员 中级资格: 软件设计师 高级资格: 系统架构设计师 初级: 科目一:计算机硬软件基础知识 150min 笔试、选择 科目二:程序设…...
Linux环境变量
目录 环境变量 基本概念 常见环境变量 查看环境变量方法 测试PATH 测试HOME 和环境变量相关的命令 环境变量的组织方式 通过代码如何获取环境变量 通过系统调用获取或设置环境变量 编辑 环境变量通常是具有全局属性的 实验 环境变量 基本概念 环境变量(environment variables…...
跨浏览器书签同步方案:WebDAV + Floccus插件实操指南
FloccusWebDAV能够帮助把多个不同浏览器书签统一私有化管理,以下是介绍: Floccus 是一个允许用户在不同浏览器和设备之间私密同步书签的扩展,开源地址:https://github.com/floccusaddon/floccusWebDAV是一种基于HTTP的协议&#…...
银河麒麟系统 达梦8 安装 dlask 框架后端环境
适配的一套环境为 dmPython2.5.8 dmSQLAlchemy1.4.39 Flask2.0.3 Flask-Cors3.0.10 Flask-SQLAlchemy2.5.1 SQLAlchemy1.4.54 Werkzeug2.2.2其中 # sqlalchemy-dm1.4.39 通过dmdbms目录内文件进行源码安装 (MindSpore) [ma-user python]$pwd /home/syl/dmdbms/drivers/python…...
代码随想录算法训练营Day31
力扣738.单调递增的数字【medium】 力扣968.监控二叉树【hard】 一、力扣738.单调递增的数字【medium】 题目链接:力扣738.单调递增的数字 视频链接:代码随想录 1、思路 先将整数转为字符串变成可迭代对象,再转为列表从后向前遍历ÿ…...
LeetCode Hot100 刷题笔记(10)—— ACM格式输入输出练习
目录 Trick: 1. 只有输出 2. 单组_AB 3. 多组_AB_EOF形式 4. 多组_AB_T组形式 5. 多组_AB_零尾形式 6. 单组_一维数组 7. 多组_二维数组_T组形式 8. 单组_二维数组 9. 多组_二维数组_T组形式 10. 单组_字符串 11. 多组_字符串_T组形式 12. 单组_二维字符数组 13. 多组_带空格的…...
iPaaS集成平台在制造业有哪些应用场景
在制造业迈向智能化的进程中,“数据不通”“系统割裂”“响应迟缓”等问题如同隐形的锁链,束缚着企业转型升级的步伐。面对设备、系统、供应链之间错综复杂的连接需求,传统定制化开发周期长、成本高,难以满足快速变化的业务需求。…...
【Docker项目实战】使用Docker部署Gitblit服务器
【Docker项目实战】使用Docker部署Gitblit服务器 一、Gitblit介绍1.1 Gitblit 介绍1.2 主要特点 二、本次实践规划2.1 本地环境规划2.2 本次实践介绍 三、本地环境检查3.1 检查Docker服务状态3.2 检查Docker版本3.3 检查docker compose 版本 四、下载Gitblit镜像五、部署Gitbli…...
基于瑞芯微RK3562 四核 ARM Cortex-A53 + 单核 ARM Cortex-M0——Linux应用开发手册
前 言 本文主要介绍TL3562-MiniEVM评估板的AMP(Asymmetric Multi-processing)开发案例,适用开发环境如下: Windows开发环境:Windows 7 64bit、Windows 10 64bit Linux开发环境:VMware16.2.5、Ubuntu20.04.6 64bit U-Boot:U-Boot-2017.09 Kernel:Linux-5.10.209 Lin…...
并查集(力扣1971)
并查集的功能:判断两个节点是否在同一个集合中/将两个节点加入同一集合中。模板如下: #include<iostream> #include<vector> using namespace std; const int n 1e6 5;//视题目具体节点数量而定,比节点数量稍大即可 vector<…...
Pinpoint - 大型分布式系统的 APM(应用性能管理)工具
文章目录 一、关于 Pinpoint最新版本(2024/10/23)-- v3.0.1PHP, PYTHON 二、概述支持的模块 一、关于 Pinpoint Pinpoint 是一个用于大型分布式系统的 APM(应用性能管理)工具,由 Java / PHP/PYTHON 编写。 受 Dapper …...
高级java每日一道面试题-2025年4月10日-微服务篇[Nacos篇]-Nacos的服务健康检查机制是如何工作的?
如果有遗漏,评论区告诉我进行补充 面试官: Nacos的服务健康检查机制是如何工作的? 我回答: Nacos 服务健康检查机制详解 Nacos 的服务健康检查机制是确保服务高可用性和可靠性的核心功能之一。它通过定期检测服务实例的状态来判断它们是否健康,并据此…...
JavaScript:表单及正则表达式验证
今天我要介绍的是在JavaScript中关于表单验证内容的知识点介绍: 关于表单验证,我接下来则直接将内容以及效果显示出来并作注解,这样可以清晰看见这个表达验证的妙用: <form id"ff" action"https://www.baidu.…...
Android 应用数据分布目录结构解析
在Android系统中,/data目录下的几个关键路径有不同的用途,主要涉及应用数据存储和用户媒体文件管理,具体如下: 1. /data/user/0/ 路径别名:等同于 /data/data/(旧路径,仍兼容)。 用途ÿ…...
Spring Boot 中的自动配置原理
2025/4/6 向全栈工程师迈进! 一、自动配置 所谓的自动配置原理就是遵循约定大约配置的原则,在boot工程程序启动后,起步依赖中的一些bean对象会自动的注入到IOC容器中。 在讲解Spring Boot 中bean对象的管理的时候,我们注入bean对…...
Java内部类详解
在Java中,内部类是一种强大的特性,允许将一个类定义在另一个类的内部。内部类提供了更好的封装性,能够访问外部类的成员,并常用于实现事件监听、适配器模式等场景。本文将深入探讨四种内部类:成员内部类、静态内部类、…...
台账自动统计——餐饮物资管理台账——仙盟共创平台——未来之窗
分类表 自动统计 创作不易,使用地址:https://mp.weixin.qq.com/s/Ok3wuSYAPhd-6N8DrK7jwg 餐饮物资管理台账自动统计能够实时、精准地呈现库存数量。通过对采购入库、领用出库、盘点盈亏等数据的自动记录与计算,管理者随时可获取准确库存信息…...
Function Calling是什么?
Function Calling(函数调用)是大型语言模型(如GPT、Claude等)中的一项关键功能,允许模型根据用户输入的需求,智能识别并返回结构化函数调用请求,从而与外部工具、API或代码进行交互。以下是详细…...
[学习] C语言数据结构深度解析:八种树结构与应用场景详解(代码示例)
C语言数据结构深度解析:八种树结构与应用场景详解 好吧,今天我们来研究树!C语言中的树。 树是计算机科学中最重要的非线性数据结构之一,广泛应用于操作系统、数据库、编译器、图形学等领域。本文将通过C语言代码示例,…...
【从零实现高并发内存池】Page Cache 从理解设计到全面实现
📢博客主页:https://blog.csdn.net/2301_779549673 📢博客仓库:https://gitee.com/JohnKingW/linux_test/tree/master/lesson 📢欢迎点赞 👍 收藏 ⭐留言 📝 如有错误敬请指正! &…...
6 CMD 与 PowerShell 指令大全、C 程序终端运行、字符编码切换指南
1 CMD 与 PowerShell 常用指令 在命令行环境中高效运行程序,掌握终端的基本操作命令至关重要。无论是 Windows 系统下的 CMD(命令提示符)还是 PowerShell,它们都配备了一系列实用的命令,助力我们管理文件、执行程序以及…...
为啥mac日历打不开浏览器
问题 换了新电脑后,mac上的日历总是没法同步google日历信息,导致经常错过会议 尝试mac日历上添加账户,结果到了打开浏览器缓解总是卡住,打不开浏览器(safari) 解决 检查默认浏览器设置确保已将所需的浏览…...
spring:注解@PostConstruct、@PreDestroy
这两个注解的功能类似标签中的init-method和destroy-method。分别在构造方法调用之后和实例释放资源之前被调用。 注解类: package com.annotation.dao.impl;import org.springframework.context.annotation.Lazy; import org.springframework.context.annotation…...
Androidjetpack之viewmodel的原理分析
前言 viewmodel是jetpack中比较重要的一个组件。如果还没有学习viewmodel不知道怎么写代码什么的,可以看一下我之前写得文章。 jetpack之ViewModel的简单使用https://blog.csdn.net/i_xiang_la_shi/article/details/147218033?fromshareblogdetail&sharetype…...
springboot启动动态定时任务
1.自定义定时任务线程池 package com.x.devicetcpserver.global.tcp.tcpscheduler;import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotatio…...
Dify智能体平台源码二次开发笔记(7) - 优化知识库pdf识别(2)
目录 前言 设计方案 代码具体优化 前言 补充前篇的一些优化。 场景是识别pdf文档,但还需要把pdf文档中的图片也保存下来,在知识库增强检索的时候,直接可以显示图片。 设计方案 1、保存知识库中的图片 2、存入我们的文件服务器中࿰…...
Linux——进程通信
我们知道,进程具有独立性,各进程之间互不干扰,但我们为什么还要让其联系,建立通信呢?比如:数据传输,资源共享,通知某个事件,或控制某个进程。因此,让进程间建…...
AF3 create_alignment_db_sharded脚本create_shard函数解读
AlphaFold3 create_alignment_db_sharded 脚本在源代码的scripts/alignment_db_scripts文件夹下。 该脚本中的 create_shard 函数的功能是将一部分链(shard_files)中的所有对齐文件写入一个 .db 文件,并返回这些链的索引信息(字节…...
Jetpack Compose 实现主页面与局部页面独立刷新的最佳实践
在 Jetpack Compose 开发中,我们经常遇到这样的需求:主页面包含局部页面,主页面刷新时需要更新局部页面,同时局部页面也需要能独立刷新。本文将介绍几种优雅的实现方案。 核心需求 主页面刷新时能触发局部页面更新局部页面能独立…...
KingbaseES之数据库审计
项目提出要配置数据库审计,来满足分保测评得要求.正好最近做过审计测试,还原下审计配置. 一.开启审计 [kingbaserack1 ~]$ vi /data/data_mysql/kingbase.conf [kingbaserack1 ~]$ sys_ctl -D /data/data_mysql restart grep -r shared_preload_libraries /data/data_mysql/k…...
类的加载过程
1、加载 双亲委派模型(启动类》扩展类》应用类) 2、验证 文件格式验证(Class 文件格式检查)元数据验证(字节码语义检查)字节码验证(程序语义检查)符号引用验证(类的正确…...
小白工具视频转 3GP,多格式转换与数据安全的完美结合,在线使用
在众多在线视频转换工具中,小白工具的视频转 3GP 功能(https://www.xiaobaitool.net/videos/convert-to-3gp/ )凭借其出色的性能和丰富的功能脱颖而出,是进行视频格式转换的优质选择。 一、强大的多格式支持 这款工具支持 MP4、…...
六根觉性:穿透表象的清净觉知之光
在喧嚣的禅堂里,老禅师轻叩茶盏,清脆的声响划破沉寂。这声"叮"不仅震动耳膜,更叩击着修行者的心性——这正是佛教揭示的六根觉性在世间万相中的妙用。当我们凝视《楞严经》中二十五圆通法门,六根觉性犹如六道澄明之光&a…...
Redis的IO多路复用
1 传统的socket编码模型 传统 Socket 模型通常采用 多线程/多进程 或 阻塞 I/O 的方式处理网络请求。以下是典型实现步骤: 创建套接字(Socket) 步骤:调用 socket() 创建一个 TCP/UDP 套接字。通常把这个套接字称为【主动套接字】…...
数据结构和算法(六)--栈队列堆
一、栈 栈(stack)是限制插入和删除只能在一个位置上进行的表,该位置是表的末端,叫做栈顶(top)。它是后进先出(LIFO)的。对栈的基本操作只有 push(进栈)和 pop(出栈&#…...
js中显示为[object Object]
现象描述: 读取文件并解析数据,遇到变量在使用时异常,通过log输出进行调试,显示为[object,Object]。 分析: [object,Object]表示这是一个对象,其构造函数返回一个对象。 解决方法: 用JSON进行…...