无锁环 C实现
无锁环MPMC目标1、实现多生产者、多消费者无锁队列2、不用互斥锁3、数组循环复用4、FIFO5、不能丢消息、不能重复读、不能读到脏数据底层载体1、固定数组大小 slots[]2、capacity 必须是 2 的幂次#includestdio.h#includestdlib.h#includepthread.h#includestdatomic.h#includestring.h/* PPT无锁环关键点 1. 环形数组缓存元素定长这里用uint32_t4字节符合PPT 4字节整数倍 2. 多生产者、多消费者MPMC 3. 不加锁全部依靠原子CAS 4. 全局共享prod_head/prod_tailcons_head/cons_tail线程本地私有副本做缓存减少共享变量访问 */typedefuint32_telem_t;// 定长元素4字节和PPT要求匹配typedefstruct{atomic_uint seq;// 槽位序列号无锁同步核心elem_tdata;}slot_t;typedefstruct{slot_t*slots;size_tcapacity;// 必须是2^Nsize_tmask;// capacity‑1代替%取模// 全局共享变量所有线程可见atomic_size_tprod_head;// 生产者headatomic_size_tprod_tail;// 生产者tailatomic_size_tcons_head;// 消费者headatomic_size_tcons_tail;// 消费者tail}lockfree_ring_t;// 创建无锁环capacity必须为2的幂lockfree_ring_t*ring_create(size_tcapacity){lockfree_ring_t*rmalloc(sizeof(lockfree_ring_t));r-capacitycapacity;r-maskcapacity-1;r-slotscalloc(capacity,sizeof(slot_t));atomic_init(r-prod_head,0);atomic_init(r-prod_tail,0);atomic_init(r-cons_head,0);atomic_init(r-cons_tail,0);for(size_ti0;icapacity;i){atomic_init(r-slots[i].seq,i);}returnr;}// 销毁voidring_destroy(lockfree_ring_t*r){free(r-slots);free(r);}/** * 多生产者入队 enqueue * 返回0成功‑1队列满 */intring_enqueue(lockfree_ring_t*r,elem_tval){size_tpos,next;// 自旋CAS争抢prod_head多生产者竞争while(1){posatomic_load_explicit(r-prod_head,memory_order_relaxed);nextpos1;size_tcons_tatomic_load_explicit(r-cons_tail,memory_order_acquire);if((next-cons_t)r-capacity){return-1;// 队列满}// CAS抢占位置if(atomic_compare_exchange_weak_explicit(r-prod_head,pos,next,memory_order_relaxed,memory_order_relaxed)){break;}}size_tidxposr-mask;slot_t*sr-slots[idx];// 等待槽位空闲上一轮消费完成while(atomic_load_explicit(s-seq,memory_order_acquire)!pos){;}s-dataval;atomic_store_explicit(s-seq,pos1,memory_order_release);// 更新prod_tail推进发布指针允许其他线程看到写入while(!atomic_compare_exchange_weak_explicit(r-prod_tail,pos,next,memory_order_release,memory_order_relaxed)){posatomic_load_explicit(r-prod_tail,memory_order_relaxed);}return0;}/** * 多消费者出队 dequeue * 返回0成功‑1队空 */intring_dequeue(lockfree_ring_t*r,elem_t*out){size_tpos,next;while(1){posatomic_load_explicit(r-cons_head,memory_order_relaxed);nextpos1;size_tprod_tatomic_load_explicit(r-prod_tail,memory_order_acquire);if(posprod_t){return-1;// 队列为空}if(atomic_compare_exchange_weak_explicit(r-cons_head,pos,next,memory_order_relaxed,memory_order_relaxed)){break;}}size_tidxposr-mask;slot_t*sr-slots[idx];// 等待生产者写完数据while(atomic_load_explicit(s-seq,memory_order_acquire)!pos1){;}*outs-data;atomic_store_explicit(s-seq,posr-capacity,memory_order_release);// 更新cons_tailwhile(!atomic_compare_exchange_weak_explicit(r-cons_tail,pos,next,memory_order_release,memory_order_relaxed)){posatomic_load_explicit(r-cons_tail,memory_order_relaxed);}return0;}// 测试多生产者多消费者#defineRING_CAP(14)// 162的幂#definePRODUCER_NUM3#defineCONSUMER_NUM2#definePER_PROD_CNT20lockfree_ring_t*g_ring;/* 函数功能向无锁环里塞数据的生产者线程 *//* 入参arg 把 tid 数字本身伪装成指针值没有对应内存*//* 返回值现成结束返回值可以给 pthread_join 拿到 */void*producer_thread(void*arg){longtid(long)arg;for(inti0;iPER_PROD_CNT;i){elem_tvtid*1000i;while(ring_enqueue(g_ring,v)!0){;// 满则自旋}printf([P%ld] enqueue: %u\n,tid,v);}returnNULL;}void*consumer_thread(void*arg){longtid(long)arg;elem_tval;inttotalPER_PROD_CNT*PRODUCER_NUM;staticatomic_int recv_cnt0;while(atomic_load(recv_cnt)total){if(ring_dequeue(g_ring,val)0){atomic_fetch_add(recv_cnt,1);printf( [C%ld] dequeue: %u\n,tid,val);}}returnNULL;}intmain(void){g_ringring_create(RING_CAP);pthread_tprods[PRODUCER_NUM];pthread_tcons[CONSUMER_NUM];for(inti0;iPRODUCER_NUM;i){pthread_create(prods[i],NULL,producer_thread,(void*)(long)i);}for(inti0;iCONSUMER_NUM;i){pthread_create(cons[i],NULL,consumer_thread,(void*)(long)i);}for(inti0;iPRODUCER_NUM;i)pthread_join(prods[i],NULL);for(inti0;iCONSUMER_NUM;i)pthread_join(cons[i],NULL);ring_destroy(g_ring);printf(all done\n);return0;}给坏代码打补丁/** * 多生产者入队 enqueue * 返回0成功‑1队列满 */intring_enqueue(lockfree_ring_t*r,elem_tval){size_tpos,next;// 自旋CAS争抢prod_head多生产者竞争while(1){posatomic_load_explicit(r-prod_head,memory_order_relaxed);nextpos1;size_tcons_tatomic_load_explicit(r-cons_tail,memory_order_acquire);if((next-cons_t)r-capacity){return-1;// 队列满}// CAS抢占位置if(atomic_compare_exchange_weak_explicit(r-prod_head,pos,next,memory_order_relaxed,memory_order_relaxed)){break;}}size_tidxposr-mask;slot_t*sr-slots[idx];// 等待槽位空闲上一轮消费完成while(atomic_load_explicit(s-seq,memory_order_acquire)!pos){;}s-dataval;atomic_store_explicit(s-seq,pos1,memory_order_release);// 更新prod_tail推进发布指针允许其他线程看到写入// 以下 for 循环函数是给注释代码打补丁注释代码存在问题/*while(!atomic_compare_exchange_weak_explicit( r-prod_tail, pos, next, memory_order_release, memory_order_relaxed )){ pos atomic_load_explicit(r-prod_tail, memory_order_relaxed); }*/for(;;){size_texpectedatomic_load_explicit(r-prod_tail,memory_order_relaxed);if(expected!pos){continue;//还没轮到我等别的线程推进}size_tdesiredexpected1;if(atomic_compare_exchange_weak_explicit(r-prod_tail,expected,desired,memory_order_release,memory_order_relaxed)){break;}// CAS失败expected已经更新下一轮重新判断}return0;}

相关新闻

wordpress独立站SEO怎么做?新手必看实操指南

wordpress独立站SEO怎么做?新手必看实操指南

都清楚做外语贸易的人, 晓得独立站是归自己所有的阵地, 然而SEO就是使得访客寻觅到你的那盏照亮物件。过去好多年份我处于这个行业历经磨砺打拼, 看见许许多多的人耗费很高昂的费用构建了站点, 但却没有任何人询问此事。实际上在技术指标网站领域里边采用wordpress独立站SEO并非…

2026/10/1 13:01:49 阅读更多 →
自定义应用层协议设计与性能优化实践

自定义应用层协议设计与性能优化实践

1. 为什么需要自定义应用层协议 在网络通信中,应用层协议是应用程序之间交流的语言。当标准协议(如HTTP、FTP等)无法满足特定业务需求时,我们就需要设计自定义协议。这种情况通常出现在: 需要极致的性能优化&#xff…

2026/10/3 18:28:13 阅读更多 →
Vue+PHP构建高并发体育赛事购票系统实战

Vue+PHP构建高并发体育赛事购票系统实战

1. 项目概述 这个基于Vue和PHP的篮球足球联赛购票系统,是我去年为一个体育赛事平台开发的核心功能模块。系统前端采用Vue.js构建响应式界面,后端使用PHP处理业务逻辑,实现了从赛事展示、座位选择到支付结算的完整购票流程。特别针对体育赛事门…

2026/10/1 13:02:15 阅读更多 →

最新新闻

Small Agent为何要从生成式推理转向分类式推理

Small Agent为何要从生成式推理转向分类式推理

1. 为什么“生成式推理”正在拖慢 Small Agent 的实际落地?你有没有遇到过这样的场景:一个轻量级的智能体(Small Agent),部署在边缘设备上,响应延迟要求低于200毫秒,但每次执行“判断用户意图”…

2026/10/14 5:15:02 阅读更多 →
工业相机接口对比:GigE、USB3、CameraLink、CoaXPress 怎么选

工业相机接口对比:GigE、USB3、CameraLink、CoaXPress 怎么选

昨天聊完黑白还是彩色,结尾说下一步该盯接口和带宽。先补一句:彩色相机要是在机内直接转成 RGB 再往外送,数据量比原始 Bayer 一下翻三倍。这事在现场可不是纸上谈兵。 去年调一台四工位的外观机,四台 500 万黑白相机,…

2026/10/14 5:15:02 阅读更多 →
电热综合能源系统优化调度模型与Matlab实现

电热综合能源系统优化调度模型与Matlab实现

1. 项目背景与核心价值去年参与某工业园区综合能源系统规划时,我们遇到一个棘手问题:园区光伏发电在午间经常出现大量弃光,而晚高峰又不得不启动昂贵的燃气锅炉供热。这种供需时空错配导致全年能源成本增加12%。这正是电热综合能源系统优化调…

2026/10/14 5:15:02 阅读更多 →
InsightFace gaze 模块视线估计完整指南:一次 160×160 推理输出 3D 视线向量

InsightFace gaze 模块视线估计完整指南:一次 160×160 推理输出 3D 视线向量

InsightFace gaze 模块视线估计完整指南:一次 160160 推理输出 3D 视线向量 【免费下载链接】insightface State-of-the-art 2D and 3D Face Analysis Project 项目地址: https://gitcode.com/GitHub_Trending/in/insightface InsightFace 是一个 2D/3D 人脸…

2026/10/14 5:15:02 阅读更多 →
工程机械现场缺的不是打卡 App,是机手经营链

工程机械现场缺的不是打卡 App,是机手经营链

01|为什么要做这个产品工程机械现场,数字化并不少。项目部有智慧工地,覆盖视频监控、人员实名、验收大屏; 设备侧搭载物联网盒子,可以采集台班、油耗、运行轨迹; 团队协作大多在用钉钉、企业微信。但机队老…

2026/10/14 5:15:02 阅读更多 →
AI工程师必修课:标量、向量、矩阵、张量的工程本质

AI工程师必修课:标量、向量、矩阵、张量的工程本质

1. 这不是数学课,是AI工程师的“肌肉记忆”训练你打开任何一本深度学习框架的官方文档,不到三分钟就会撞上这几个词:标量、向量、矩阵、张量。它们不像“卷积”“反向传播”那样自带技术光环,也不像“Transformer”“LoRA”那样刷…

2026/10/14 5:14:02 阅读更多 →

日新闻

AnyPS5通用适配层设计:兼容性与性能的工程取舍

AnyPS5通用适配层设计:兼容性与性能的工程取舍

1. 从"AnyPS5"这个名字说起:它到底想解决什么问题第一次看到"AnyPS5"这个标题,我脑子里冒出来的第一个念头是:这大概率是一个围绕"跨平台运行"或者"通用适配"做文章的项目。名字里的"Any"…

2026/10/14 0:00:41 阅读更多 →
Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

1. 项目概述:Flutter跨平台二手交易应用开发作为一名长期从事移动应用开发的工程师,我最近完成了一个基于Flutter框架的二手物品交易平台项目。这个项目最吸引我的地方在于它完美结合了Flutter的跨平台优势与HarmonyOS的生态特性,实现了"…

2026/10/14 0:00:41 阅读更多 →
DFS算法解决飞机降落调度问题实战

DFS算法解决飞机降落调度问题实战

1. 项目背景与核心思路飞机降落问题是一个经典的调度优化场景,也是算法竞赛和面试中的高频题目。这个题目要求我们合理安排多架飞机的降落顺序和时间,确保所有飞机都能安全着陆而不发生冲突。在实际航空管制中,这类问题直接关系到飞行安全和机…

2026/10/14 0:00:41 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/14 3:30:28 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/13 16:22:04 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/14 3:29:58 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 22:01:27 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 14:57:39 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 18:11:17 阅读更多 →