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

MQTTClient.c的线程模型与异步事件驱动

MQTTClient.c的线程模型与异步事件驱动


1. 多线程架构设计

MQTTClient.c通过分离网络I/O和用户逻辑线程实现异步通信,核心设计如下:

sequenceDiagramparticipant 主线程 as 主线程(用户调用)participant 发送队列 as 发送队列participant 网络线程 as 网络线程(后台循环)participant Socket as 网络Socket主线程->>发送队列: MQTTPublish()/MQTTSubscribe()激活 发送队列网络线程->>发送队列: 从队列取出待发报文发送队列-->>网络线程: 序列化后的数据网络线程->>Socket: sendPacket()Socket-->>网络线程: 接收响应(如PUBACK)网络线程->>主线程: 触发回调(如messageHandler)主线程->>主线程: 处理业务逻辑

关键设计点

  • 主线程:用户直接调用API(如MQTTPublish),将请求封装为协议报文并压入发送队列,避免阻塞。
  • 网络线程:由MQTTStartTask启动,执行MQTTRun循环,轮询Socket事件、处理报文和心跳。
  • 队列缓冲:发送队列作为线程间通信桥梁,通过互斥锁保证原子操作。

2. 事件驱动的状态机

连接与订阅过程通过状态机管理,确保协议流程合规:

调用connect()
TCP握手成功
发送CONNECT报文
收到CONNACK且rc=0
超时或rc≠0
调用MQTTSubscribe()
发送SUBSCRIBE报文
收到SUBACK
进入消息循环
初始化
TCP连接
CONNECT发送
等待CONNACK
连接成功
连接失败
订阅中
等待SUBACK
订阅完成

状态机特性

  • 连接阶段:通过connState变量跟踪状态,失败时自动回退。
  • 订阅同步:维护pending_subscriptions列表,在收到SUBACK后匹配Packet ID并触发回调。

3. 心跳保活与超时重传
timelinetitle 心跳与重传时序(QoS 1示例)section 心跳保活PINGREQ发送 : 2023-10-01 10:00:00PINGRESP接收 : 2023-10-01 10:00:02(成功)section 消息重传发送PUBLISH : 2023-10-01 10:00:05超时未收到PUBACK : 2023-10-01 10:00:10指数退避重传 : 2023-10-01 10:00:15(延迟5s)

实现细节

  • 心跳保活:通过lastSentlastReceived时间戳计算闲置时间,超时发送PINGREQ。
  • 重传队列:维护outboundMsgs队列,记录未确认的QoS>0消息,重传时采用指数退避策略(如1s, 2s, 4s)。
  • ACK匹配:通过Packet ID关联请求与响应,确保消息可靠性。

4. 线程安全与锁机制
条件变量优化
网络线程休眠
队列为空
新消息入队
触发cond_signal
网络线程唤醒
线程安全设计
加锁mutex
主线程写队列
操作共享资源
释放mutex
网络线程读队列

关键机制

  • 互斥锁(Mutex):保护messageQueueoutboundMsgs,防止竞争条件。
  • 条件变量(Condition Variable):当发送队列为空时,网络线程休眠;新消息到达时通过pthread_cond_signal唤醒,减少CPU空转。

5. 异步回调的实现
网络线程
收到PUBLISH
解析Topic和Payload
匹配订阅的messageHandler
回调执行策略
同步执行
提交到线程池

回调策略

  • 同步执行:直接在网络线程中触发回调,简单但可能阻塞I/O(默认模式)。
  • 线程池执行:通过ThreadPool异步处理回调,避免阻塞(需用户自定义线程池实现)。
  • 内存管理扩展:允许用户替换malloc/free,例如使用静态内存池管理Payload,避免碎片化。

6. 性能优化与设计权衡
30% 40% 15% 15% 资源占用分布 协议解析 网络I/O 锁竞争开销 回调处理

优化方向

  • 零拷贝优化:Payload直接引用接收缓冲区,减少内存复制(QoS 0场景)。
  • 批处理发送:合并多个小报文,减少系统调用次数。
  • 无锁队列:在单生产者-单消费者场景下,使用Ring Buffer替代互斥锁。

总结

MQTTClient.c通过多线程分离、状态机驱动和精细的锁机制,实现了高效的异步事件处理模型。其设计在资源受限的嵌入式场景中表现优异,同时通过可扩展的回调接口支持复杂业务逻辑。未来可结合无锁数据结构和线程池进一步优化高并发场景下的吞吐量与实时性。

相关文章:

MQTTClient.c的线程模型与异步事件驱动

MQTTClient.c的线程模型与异步事件驱动 1. 多线程架构设计 MQTTClient.c通过分离网络I/O和用户逻辑线程实现异步通信,核心设计如下: sequenceDiagramparticipant 主线程 as 主线程(用户调用)participant 发送队列 as 发送队列pa…...

《Learning Langchain》阅读笔记3-基于 Gemini 的 Langchain如何从LLMs中获取特定格式

纯文本输出是有用的,但在某些情况下,我们需要 LLM 生成结构化输出,即以机器可读格式(如 JSON、XML 或 CSV)或甚至以编程语言(如 Python 或 JavaScript)生成的输出。当我们打算将该输出传递给其他…...

AI Agents系列之构建多智能体系统

🧠 向所有学习者致敬! “学习不是装满一桶水,而是点燃一把火。” —— 叶芝 我的博客主页: https://lizheng.blog.csdn.net 🌐 欢迎点击加入AI人工智能社区! 🚀 让我们一起努力,共创…...

OJ笔试强训_1至24天

OJ笔试强训 Day01 [NOIP2010]数字统计_牛客题霸_牛客网 点击消除_牛客题霸_牛客网 两个数组的交集_牛客题霸_牛客网 Day02 牛牛的快递_牛客题霸_牛客网 最小花费爬楼梯_牛客题霸_牛客网 数组中两个字符串的最小距离__牛客网 Day03 简写单词_牛客题霸_牛客网 dd爱框框_…...

3款顶流云电脑与传统电脑性能PK战:START云游戏/无影云/ToDesk云电脑谁更流畅?

这里写目录标题 一、前言二、本地机器配置环境三、START云游戏/无影云/ToDesk云电脑配置对比3.1 START云游戏3.2 无影云个人版3.3 ToDesk云电脑 四、本地电脑与云电脑性能实战4.1 游戏场景体验4.1.1 本地电脑测试4.1.2 云电脑测试英雄联盟黑神话悟空其他游戏 4.2 主流设计场景体…...

java IO/NIO/AIO

(✪▽✪)曼波~~~~!让曼波用最可爱的赛马娘方式给你讲解吧!(⁄ ⁄•⁄ω⁄•⁄ ⁄) 🎠曼波思维导图大冲刺(先看框架再看细节哦): 📚 解释 Java 中 IO、NIO、AIO 的区别和适用场景: …...

java输出、输入语句

先创建一个用于测试的java 编写程序 #java.util使java标准库的一个包,这里拉取Scanner类 import java.util.Scanner;public class VariableTest {public static void main(String[] args) {#创建一个 Scanner 对象Scanner scanner new Scanner(System.in);System.…...

宏基因组产品升级——抗菌肽数据库APD

抗菌肽(Antimicrobial Peptides,简称AMPs)是一类存在于多种生物体中的天然分子。它们在抵御微生物感染中扮演着重要角色,发挥着先天免疫反应的作用。抗菌肽功能分类广泛,包括:抗菌,抗生物膜&…...

大数据面试问答-Spark

1. Spark 1.1 Spark定位 "Apache Spark是一个基于内存的分布式计算框架,旨在解决Hadoop MapReduce在迭代计算和实时处理上的性能瓶颈。 1.2 核心架构 Spark架构中有三个关键角色: Driver:解析代码生成DAG,协调任务调度&a…...

线程池七个参数的含义

Java中的线程池里七个参数的以及其各自的含义 面试题:说一下线程池七个参数的含义? 所谓的线程池的 7 大参数是指,在使用 ThreadPoolExecutor 创建线程池时所设置的 7 个参数,如以下源码所示: public ThreadPoolExe…...

Windows suwellofd 阅读器-v5.0.25.0320

Windows suwellofd 阅读器 链接:https://pan.xunlei.com/s/VOO7tUkTHHTTjSe39CeVkUHbA1?pwd3ibx# OFD(Open Fixed-layout Document) , 数科OFD阅读器支持国标版式、可信阅读、是电子发票、电子证照,电子病历等电子文件理想阅读工具。 多格…...

三大等待和三大切换

三大等待 1、三大等待:等待的方式有三种:强制等待,隐性等待,显性等待。 1、强制等待:time.sleep(2),秒 优点:使用简单缺点:等待时间把握不准,容易造成时间浪费或者等待时…...

告别定时任务!用Dagster监听器实现秒级数据响应自动化

在数据管道开发中,我们经常面临需要根据外部事件触发计算任务的场景。传统基于时间的调度方式存在资源浪费和时效性不足的问题。本文将通过Dagster的**传感器(Sensor)**功能,演示如何构建事件驱动的数据处理流程。 场景模拟&…...

一文读懂WPF系列之MVVM

WPF MVVM 什么是MVVMWPF为何使用MVVM机制WPFMVVM 的实现手段 INotifyPropertyChanged​数据绑定的源端通知​​原理 PropertyChanged事件双向绑定的完整条件常见疑惑问题 什么是MVVM 翻译全称就是 model-view-viewmodel 3部分内容 以wpf的概念角度来解释就是 数据库数据源模型…...

【Unity】打包TextMeshPro的字体

前言 在Unity中,TextMeshPro与常规 Text 组件相比提供了更高级的文本呈现功能,TextMesh Pro 可以处理各种语言,包括中文。我们可以轻松地在 Unity 项目中使用中文,而不必担心字体和布局问题。TextMeshPro需要的字体资源就需要我们…...

51单片机实验五:A/D和D/A转换

一、实验环境与实验器材 环境:Keli,STC-ISP烧写软件,Proteus. 器材:TX-1C单片机(STC89C52RC)、电脑。 二、 实验内容及实验步骤 1.A/D转换 概念:模数转换是将连续的模拟信号转换为离散的数字信…...

使用VHD虚拟磁盘安装双系统,避免磁盘分区

前言 很多时候,我们对现在的操作系统不满意,就想要自己安装一个双系统 但是安装双系统又涉及到硬盘分区,非常复杂,容易造成数据问题 虚拟机的话有经常用的不爽,这里其实有一个介于虚拟机和双系统之间的解决方法,就是使用虚拟硬盘文件安装系统. 相当于系统在机上…...

Kafka消费者端重平衡流程

重平衡的完整流程需要消费者 端和协调者组件共同参与才能完成。我们先从消费者的视角来审视一下重平衡的流程。在消费者端,重平衡分为两个步骤:分别是加入组和等待领导者消费者(Leader Consumer)分配方案。这两个步骤分别对应两类…...

Django之modelform使用

Django新增修改数据功能优化 目录 1.新增数据功能优化 2.修改数据功能优化 在我们做数据优化处理之前, 我们先回顾下传统的写法, 是如何实现增加修改的。 我们需要在templates里面新建前端的页面, 需要有新增还要删除, 比如说员工数据的新增, 那需要有很多个输入框, 那html…...

云轴科技ZStack入选中国人工智能产业发展联盟《大模型应用交付供应商名录》

2025年4月8日至9日,中国人工智能产业发展联盟(以下简称AIIA)第十四次全体会议暨人工智能赋能新型工业化深度行(南京站)在南京召开。工业和信息化部科技司副司长杜广达,中国信息通信研究院院长、中国人工智能…...

写论文时降AIGC和降重的一些注意事项

‘ 写一些研究成果,英文不是很好,用有道翻译过来句子很简单,句型很单一。那么你会考虑用ai吗? 如果语句太正式,高级,会被误判成aigc ,慎重选择ai润色。 有的话就算没有用ai生成,但…...

AI 编程工具—如何在 Cursor 中集成使用 MCP工具

AI 编程工具—如何在 Cursor 中集成使用 MCP工具 这里我们给出了常用的MCP 聚合工具,也就是我们可以在这些网站找MCP服务 这是一个MCP Server共享平台,用户可以在上面发布和下载MCP Server配置。在这里可以选择你需要的MCP 服务。 如果你不知道你的mcp 对应的server 名称也不…...

基础算法篇(5)(蓝桥杯常考点)—动态规划(C/C++)

文章目录 动态规划前言线性dp路径类dp经典线性dp背包问题分类01背包问题完全背包问题多重背包分组背包问题混合背包问题多维费用的背包问题区间dp 动态规划 前言 在竞赛中,如果遇到动态规划的题目,只要不是经典题型,那么大概率就是以压轴题的…...

MLLMS_KNOW尝鲜版

背景(个人流水账,可毫不犹豫跳过) 最近项目中有涉及到小物体检测的内容,昨天晚上讨论的时候有提出是否可以将关注区域放大的idea,不过后来没有就着这个东西深入,结果好巧不巧地,今天关注到这篇…...

《软件设计师》复习笔记(12.2)——成本管理、配置管理

目录 一、项目成本管理 1. 定义 2. 主要过程 3. 成本类型 4. 其他概念 真题示例: 二、软件配置管理 1. 定义 2. 主要活动 3. 配置项 4. 基线(Baseline) 5. 配置库类型 真题示例: 一、项目成本管理 1. 定义 在批准…...

《AI赋能职场:大模型高效应用课》第8课 AI辅助职场沟通与协作

【本课目标】 掌握AI辅助邮件、沟通话术的优化技巧。学习利用AI快速生成高效的会议纪要。通过实操演练,提升职场沟通效率与协作能力。 【准备工具】 DeepSeek大模型(deepseek.com)百度文心一言(yiyan.baidu.com) 一…...

Spring 中的 @Cacheable 缓存注解

1 什么是缓存 第一个问题,首先要搞明白什么是缓存,缓存的意义是什么。 对于普通业务,如果要查询一个数据,一般直接select数据库进行查找。但是在高流量的情况下,直接查找数据库就会成为性能的瓶颈。因为数据库查找的…...

settimeout和setinterval区别

1. setTimeout:单次延迟执行 语法: const timeoutId setTimeout(callback, delay, arg1, arg2, ...); 核心功能:在指定的 delay(毫秒)后,执行一次 callback 函数。 参数: callback&#x…...

UE5编辑器静止状态下(非 Play 模式)睫毛和眼睛的渲染是正常的,而在 Play 模式下出现模糊

这通常指向以下几个 运行时(Runtime) 特有的原因: 抗锯齿 (Anti-Aliasing) 方法,特别是 Temporal Anti-Aliasing (TAA): 这是最可能的原因。 UE5 默认启用的 TAA 通过混合多帧信息来平滑边缘和减少闪烁,尤其是在运动中…...

怎样选择适合网站的服务器带宽?

合适的服务器带宽对于网站的需求起着至关重要的作用,服务器带宽会直接影响到网站的访问速度和用户体验,本文将介绍一下企业该怎样选择适合网站需求的服务器带宽! 不同类型的网站对于服务器带宽的需求也是不同的,小型博客网站的访问…...