当前位置: 首页 > news >正文

单片机开发进阶技巧:(三)生产者-消费者模型

上一篇下一篇
如何判断一个浮点型运算结果是否为整数

目 录

  • 生产者-消费者模型
    • 1)定义
    • 2)核心同步问题
    • 3)实现方式
      • 3.1)基于信号量的经典方案
      • 3.2)在 RTOS 中(如 FreeRTOS)
    • 4)实际工作中常见的应用场景
    • 5)总结

生产者-消费者模型

1)定义

生产者-消费者模型 是并发编程中最经典的设计模式之一,用于解决多线程/多进程之间数据传递与协作的问题。

  • 生产者(Producer):负责生成数据(比如传感器采集、网络接收、文件读取)。
  • 消费者(Consumer):负责处理数据(比如计算、显示、存储、转发)。
  • 共享缓冲区(Buffer):一个固定大小的队列或环形缓冲区,生产者把数据放进去,消费者从里面取出来。

三者关系:[生产者] —(写入)—> [共享缓冲区] —(读取)—> [消费者]

为什么需要这个模型?

好处说明
解耦生产者和消费者互不依赖,可以独立变化
平衡速度差异生产者快、消费者慢时,数据暂存缓冲区,不会丢失或阻塞
异步处理生产者在产生数据后不必等消费者处理完,可以立刻去做下一件事
支持并发多个生产者和多个消费者可以同时工作

2)核心同步问题

共享缓冲区是临界资源,需要解决两个问题:

问题描述典型解决方式
互斥同一时刻只能有一个线程修改缓冲区互斥锁(mutex)
同步缓冲区满时生产者必须等待,缓冲区空时消费者必须等待信号量(semaphore)

3)实现方式

3.1)基于信号量的经典方案

// 假设有一个长度为 N 的环形缓冲区sem_tempty_slots;// 初始值为 N(空位数)sem_tfilled_slots;// 初始值为 0(已填数据数)mutex_tbuffer_mutex;// 保护缓冲区操作voidproducer(){while(1){item=produce_item();sem_wait(&empty_slots);// 等有空位mutex_lock(&buffer_mutex);insert_item(item);// 放入缓冲区mutex_unlock(&buffer_mutex);sem_post(&filled_slots);// 通知有新数据}}voidconsumer(){while(1){sem_wait(&filled_slots);// 等有数据mutex_lock(&buffer_mutex);item=remove_item();// 取出缓冲区mutex_unlock(&buffer_mutex);sem_post(&empty_slots);// 通知有空位consume_item(item);}}

3.2)在 RTOS 中(如 FreeRTOS)

通常会用消息队列(Queue)直接实现,队列本身已经内置了互斥和同步机制:

QueueHandle_t xQueue=xQueueCreate(QUEUE_LENGTH,sizeof(Data_t));// 生产者voidvProducerTask(void*pvParameters){Data_t data;// ... 生成数据xQueueSend(xQueue,&data,portMAX_DELAY);}// 消费者voidvConsumerTask(void*pvParameters){Data_t data;xQueueReceive(xQueue,&data,portMAX_DELAY);// ... 处理数据}

4)实际工作中常见的应用场景

场景生产者消费者缓冲区
日志系统各个业务线程产生日志单独的日志线程写入文件无锁环形缓冲区
串口通信串口接收中断(ISR)数据解析线程RingBuffer
网络包处理网卡驱动接收数据协议栈线程(LwIP)pbuf 链表 / 队列
传感器数据采集定时器中断采集 ADC数据处理/上传线程双缓冲或队列

5)总结

生产者消费者模型就是通过一个共享的缓冲区,把“生产数据”和“消费数据”两个动作分开,让它们可以并发、异步地执行,并利用互斥和同步机制保证数据安全与流程协调


http://www.cnnetsun.cn/news/3581139.html

相关文章:

  • 《倒像》预告片技术解析:低成本短片创作的视觉语言与制作实践
  • 嵌入式Linux驱动开发面试20问与实战解析
  • 解决Android进程保活挑战的KeepAlive技术革新方案
  • Unity UIEffect:替代粒子系统,实现高性能UI特效的实战指南
  • Unity 3D手游开发入门:从环境搭建到性能优化的完整指南
  • 鸿蒙 ArkTS 实战:Important File Backup 从重要文件备份到生活安全工具完整解析
  • FreeCAD扫掠操作详解:参数化3D建模高效创建复杂几何形状
  • [技术讨论] 用Wireshark抓包无线网络数据,抓到好多东西,还蛮好玩的
  • 摔箱测试不是随便摔!ASTM D4169自由跌落测试和旋转棱跌落测试有何区别!
  • 中南林业科技大学食堂美食评价系统任务书
  • Spring Batch企业级批处理系统设计与优化实践
  • 嵌入式视频处理实战:HDVPSS缩放器与VENC编码器寄存器配置详解
  • 本地AI视频生成:从Stable Video Diffusion到ComfyUI实战指南
  • 大模型分类体系
  • 强化学习 / OPD】OpenClaw-RL 源码阅读笔记 --- (7)--- Policy Serving
  • TI C6000 DSP SYSCFG模块配置详解:从CHIPSIG到CFGCHIP的嵌入式系统核心控制
  • UVa 11669 Non Decreasing Prime Sequence
  • ComfyUI与Hermes Agent:自然语言控制AI绘画工作流
  • 临沂鑫旺2026 耐腐材质告别后期频繁更换
  • FTP服务部署与优化:vsftpd实战指南
  • Seedance3.0本地部署实战:免费AI视频生成与绘画完整指南
  • Spark MLlib分布式机器学习框架入门与实践
  • 嵌入式外设驱动核心:I2C与LCD控制器寄存器配置与中断处理实战
  • 前端开发环境配置常见问题与解决方案
  • AI工具如何提升学术论文写作效率与质量
  • 2026年AI学术写作工具评测与应用指南
  • Informer:长序列时间预测的Transformer优化方案
  • Open CaptchaWorld:多模态验证码测试与评估平台
  • Unity UGUI性能优化实战:数字孪生项目中的Canvas渲染与控件优化策略
  • 跨境价格监控为什么会误判?关键在地区上下文校验