C++笔记之不同框架中事件循环的核心函数:io_run()、ros_spin()、app_exec()
C++笔记之不同框架中事件循环的核心函数:io_run()、ros_spin()、app_exec()
code review!
参考笔记
1.qt-C++笔记之使用QtConcurrent异步地执行槽函数中的内容,使其不阻塞主界面
2.qt-C++笔记之QThread使用
3.qt-C++笔记之多线程架构模式:事件信号监听线程中除了while循环外让线程一直活着的方法(笔记一)
4.qt-C++笔记之多线程架构模式:事件信号监听线程中除了while循环外让线程一直活着的方法(笔记二)
5.ROS笔记之ros::spin()、ros::spinOnce()的区别
6.C++笔记之不同框架中事件循环的核心函数:io_run()、ros_spin()、app_exec()
文章目录
- C++笔记之不同框架中事件循环的核心函数:io_run()、ros_spin()、app_exec()
- 1. `io.run()`(Boost.Asio)
- 功能
- 退出条件
- 特点
- 2. `ros::spin()`(ROS 框架)
- 功能
- 退出条件
- 特点
- 3. `app.exec()`(Qt 框架)
- 功能
- 退出条件
- 特点
- 4.对比表格
- 5.为什么 `io.run()` 会主动退出,而其他两个不会?
- 6.如何让 `io.run()` 不主动退出?
1. io.run()
(Boost.Asio)
功能
io.run()
是 Boost.Asio 中的事件循环函数,用于处理异步操作和事件。它会以同步方式运行,直到所有已注册的异步操作(包括定时器、网络 I/O 和其他事件)完成。- 具体行为:
- 等待事件(如定时器到期、异步 I/O 操作完成)。
- 当事件触发时,调用相应的回调函数。
- 如果没有更多的事件或异步操作可处理,
io.run()
会自动退出。
退出条件
- 没有活跃的异步操作:如果所有注册的异步任务(如定时器、异步 I/O 等)都完成,
io.run()
会退出。 - 手动停止:可以通过调用
io_context::stop()
或io_service::stop()
主动停止事件循环,使io.run()
立即退出。
特点
io.run()
会根据注册的异步操作动态决定其生命周期。当没有更多事件需要处理时,它将主动退出,以实现高效资源管理。
2. ros::spin()
(ROS 框架)
功能
ros::spin()
是 ROS(Robot Operating System)中的事件循环函数,用于处理 ROS 节点的回调事件(如消息订阅、服务请求)。- 具体行为:
- 等待 ROS 事件(如消息到达、定时器触发)。
- 当事件触发时,调用相应的回调函数。
- 持续运行,直到收到退出信号。
退出条件
- 手动退出:
- 调用
ros::shutdown()
显式终止事件循环。 - 或者按下
Ctrl+C
,触发SIGINT
信号,ROS 会自动调用ros::shutdown()
。
- 调用
- ROS Master 断开:如果 ROS 节点与 ROS Master 的连接丢失,
ros::spin()
可能会退出。
特点
- 与
io.run()
不同,ros::spin()
的设计目的是持续运行,以保持节点对 ROS 消息和事件的监听。因此,它不会因为没有事件处理而主动退出。
3. app.exec()
(Qt 框架)
功能
app.exec()
是 Qt 框架中的事件循环函数,用于运行 GUI 应用程序的主事件循环。它负责处理用户输入(如鼠标点击、键盘输入)、定时器事件、窗口渲染等。- 具体行为:
- 运行事件循环,监听和分发系统事件(如用户输入事件)。
- 当事件触发时,调用对应的槽函数或回调函数。
- 保持运行,直到应用程序退出。
退出条件
- 显式退出:
- 调用
QCoreApplication::quit()
或QApplication::exit()
,退出事件循环。 - 用户关闭主窗口(如果设置了关闭主窗口会退出应用的逻辑)。
- 调用
- 系统强制终止:如任务管理器强制关闭程序。
特点
- 与
ros::spin()
类似,app.exec()
的事件循环设计为持续运行,以确保 GUI 应用程序能够实时响应用户输入。
4.对比表格
框架 | 核心函数 | 是否持续监听 | 持续监听的条件 |
---|---|---|---|
Boost.Asio | io_context::run() | 有条件地持续 | 需有未决异步操作或保有executor_work_guard 对象 |
ROS | ros::spin() | 是 | 节点未关闭,持续运行 |
Qt | QApplication::exec() | 是 | 应用程序未退出,事件循环自动运行 |
5.为什么 io.run()
会主动退出,而其他两个不会?
-
设计目的不同:
io.run()
的设计目的是高效处理异步操作,并在没有更多事件需要处理时立即退出,以节省资源。ros::spin()
和app.exec()
的设计目的是保持程序运行以持续监听事件(如用户输入或 ROS 消息),因此不会主动退出。
-
事件循环的生命周期管理:
- 在
io.run()
中,事件循环的生命周期由当前注册的异步操作决定。如果没有活跃的异步操作,事件循环自动结束。 - 在
ros::spin()
和app.exec()
中,事件循环的生命周期与程序的整体生命周期绑定,不会因为没有事件处理而退出。
- 在
6.如何让 io.run()
不主动退出?
如果希望 io.run()
的事件循环一直运行,可以确保至少有一个活跃的异步操作。以下是几种常见方法:
-
保持活跃的异步操作
- 确保在异步任务完成后,重新启动新的异步操作。例如,在定时器到期后,继续重新设置计时器。
-
使用空闲工作对象
- 使用
boost::asio::executor_work_guard
或boost::asio::io_service::work
保持io_context
活跃,即使没有其他异步操作:boost::asio::io_context io; auto work = boost::asio::make_work_guard(io);io.run(); // 不会主动退出
- 使用
-
定时器循环调用
- 使用定时器在事件循环内持续触发事件:
void keepAlive(boost::asio::steady_timer& timer) {timer.expires_after(std::chrono::seconds(1));timer.async_wait([&](const boost::system::error_code& error) {if (!error) {std::cout << "Still running..." << std::endl;keepAlive(timer); // 重新启动定时器}}); }
- 使用定时器在事件循环内持续触发事件:
通过这些方法,可以防止 io.run()
提前退出,使事件循环持续运行并监听事件。
相关文章:
C++笔记之不同框架中事件循环的核心函数:io_run()、ros_spin()、app_exec()
C笔记之不同框架中事件循环的核心函数:io_run()、ros_spin()、app_exec() code review! 参考笔记 1.qt-C笔记之使用QtConcurrent异步地执行槽函数中的内容,使其不阻塞主界面 2.qt-C笔记之QThread使用 3.qt-C笔记之多线程架构模式:事件信号监…...

C++异常处理
目录 一、异常的概念 二、异常的使用 (1)异常的抛出和捕获 (2)异常的重新抛出 (3)异常安全 (4)异常规范 三、自定义异常体系 四、c标注异常体系 五、异常的优缺点 在之前我们…...

【数据结构】哈希 ---万字详解
unordered系列关联式容器 在C98中,STL提供了底层为红黑树结构的一系列关联式容器,在查询时效率可达到log_2 N,即最差情况下需要比较红黑树的高度次,当树中的节点非常多时,查询效率也不理想。最好 的查询是,…...
4399大数据面试题及参考答案(数据分析和数据开发)
对数据分析的理解 数据分析是一个从数据中提取有价值信息以支持决策的过程。它涵盖了数据收集、清洗、转换、建模和可视化等多个环节。 首先,数据收集是基础。这包括从各种数据源获取数据,例如数据库、文件系统、网络接口等。这些数据源可以是结构化的数据,如关系型数据库中…...

快速理解倒排索引在ElasticSearch中的作用
一.基础概念 定义: 倒排索引是一种数据结构,用来加速文本数据的搜索和检索,和传统的索引方式不同,倒排索引会被每个词汇项与包含该词汇项的文档关联起来,从而去实现快速的全文检索。 举例: 在传统的全文…...

C++趣味编程玩转物联网:基于树莓派Pico控制无源蜂鸣器-实现音符与旋律的结合
无源蜂鸣器是一种多功能的声音输出设备,与有源蜂鸣器相比,它能够通过不同频率的方波生成丰富多样的音调。本项目使用树莓派Pico开发板,通过编程控制无源蜂鸣器播放经典旋律《归来有风》。本文将详细介绍项目实现中的硬件连接、C++代码解析,以及无源蜂鸣器的工作原理。 一、…...
《RuoYi基于SpringBoot+Vue前后端分离的Java快速开发框架学习》系列博客_Part4_三模态融合
系列博客目录 文章目录 系列博客目录目标Step1:之前工作形成子组件Step2:弥补缺失的文本子组件,同时举例如何子组件向父组件传数据Step3:后端代码需要根据上传的文件传给python服务器Step4:python服务器进行分析 目标 实现三模态融合,将文本、图片、音频…...

springboot365高校疫情防控web系统(论文+源码)_kaic
毕 业 设 计(论 文) 题目:高校疫情防控的设计与实现 摘 要 互联网发展至今,无论是其理论还是技术都已经成熟,而且它广泛参与在社会中的方方面面。它让信息都可以通过网络传播,搭配信息管理工具可以很好地为…...

STM32 USART串口数据包
单片机学习! 目录 前言 一、数据包 二、HEX数据包 三、文本数据包 四、HEX数据包和文本数据包优缺点 4.1 HEX数据包 4.2 文本数据包 五、HEX数据包接收 六、文本数据包接收 总结 前言 本文介绍了串口数据包收发的思路和流程。 一、数据包 数据包的作用是把一个个单独…...
【LC】3232. 判断是否可以赢得数字游戏
题目描述: 给你一个 正整数 数组 nums。 Alice 和 Bob 正在玩游戏。在游戏中,Alice 可以从 nums 中选择所有个位数 或 所有两位数,剩余的数字归 Bob 所有。如果 Alice 所选数字之和 严格大于 Bob 的数字之和,则 Alice 获胜。如果…...

Linux基础学习--vi与vim
0.绪论 前面的内容基本学完了相关命令行,后面进行shell与shell script的学习。第一部分就是编辑器的学习,之前有写过vi/vim编辑器,但是我看了一下鸟哥这个非常详细,还是打算重头学习一下。 1.vi/vim的使用 一般命令模式(command…...
JavaScript 高级教程:异步编程、面向对象与性能优化
在前两篇教程中,我们学习了 JavaScript 的基础和进阶内容。这篇文章将带领你进入更深层次,学习 JavaScript 的异步编程模型、面向对象编程(OOP),以及性能优化的技巧。这些内容对于构建复杂、流畅的前端应用至关重要。 …...

qt QToolBox详解
1、概述 QToolBox是Qt框架中的一个控件,它提供了一个带标签页的容器,用户可以通过点击标签页标题来切换不同的页面。QToolBox类似于一个带有多页选项卡的控件,但每个“选项卡”都是一个完整的页面,而不仅仅是标签。这使得QToolBo…...
翁知宜荣获“易学名师”与“国学文化传承人”称号
在2024年10月19日举行的北京第六届国学文化传承峰会上,翁知宜老师以其在易学界的卓越成就和对国学文化的传承与发扬,荣获“易学名师”和“国学文化传承人”两项荣誉称号。 翁知宜老师在易经学术竞赛中荣获第一名,其深厚的易学造诣和对玄学学…...

20241128解决Ubuntu20.04安装libwxgtk3.0-dev异常的问题
20241128解决Ubuntu20.04安装libwxgtk3.0-dev异常的问题 2024/11/28 16:17 缘起:中科创达的高通CM6125开发板的Android10的编译环境需要。 安装异常:rootrootrootroot-X99-Turbo:~$ rootrootrootroot-X99-Turbo:~$ sudo apt-get install libwxgtk3.0-de…...
sql分类
SQL(Structured Query Language)是一种用于管理和操作关系数据库管理系统(RDBMS)的编程语言。SQL 可以分为几个主要类别,每个类别都有其特定的用途和功能。以下是 SQL 的主要分类: 1. 数据定义语言&#x…...
stm32里一个定时器可以提供多路信号吗?
在STM32中,一个定时器通常只能提供一组信号(如输出PWM波形、定时中断等)。但是,定时器的多个通道可以提供不同的信号。例如,STM32的定时器可以通过不同的输出通道产生多种PWM信号,每个通道可以配置为不同的…...

Java安全—原生反序列化重写方法链条分析触发类
前言 在Java安全中反序列化是一个非常重要点,有原生态的反序列化,还有一些特定漏洞情况下的。今天主要讲一下原生态的反序列化,这部分内容对于没Java基础的来说可能有点难,包括我。 序列化与反序列化 序列化:将内存…...
2023考研王道计算机408数据结构+操作系统+计算机组成原理+计算机网络
from: https://blog.csdn.net/weixin_46118419/article/details/125611299 写得很好! 轻重缓急 2023考研计算机408【王-道计算机408】数据结构操作系统计算机组成原理计算机网络 网盘-链接:https://pan.baidu.com/s/13JraxUYwNVPeupdzprx5hA?pwd5h3d 提…...
YOLOv8-ultralytics-8.2.103部分代码阅读笔记-files.py
files.py ultralytics\utils\files.py 目录 files.py 1.所需的库和模块 2.class WorkingDirectory(contextlib.ContextDecorator): 3.def spaces_in_path(path): 4.def increment_path(path, exist_okFalse, sep"", mkdirFalse): 5.def file_age(path__fi…...
conda相比python好处
Conda 作为 Python 的环境和包管理工具,相比原生 Python 生态(如 pip 虚拟环境)有许多独特优势,尤其在多项目管理、依赖处理和跨平台兼容性等方面表现更优。以下是 Conda 的核心好处: 一、一站式环境管理:…...

手游刚开服就被攻击怎么办?如何防御DDoS?
开服初期是手游最脆弱的阶段,极易成为DDoS攻击的目标。一旦遭遇攻击,可能导致服务器瘫痪、玩家流失,甚至造成巨大经济损失。本文为开发者提供一套简洁有效的应急与防御方案,帮助快速应对并构建长期防护体系。 一、遭遇攻击的紧急应…...
Linux链表操作全解析
Linux C语言链表深度解析与实战技巧 一、链表基础概念与内核链表优势1.1 为什么使用链表?1.2 Linux 内核链表与用户态链表的区别 二、内核链表结构与宏解析常用宏/函数 三、内核链表的优点四、用户态链表示例五、双向循环链表在内核中的实现优势5.1 插入效率5.2 安全…...

VB.net复制Ntag213卡写入UID
本示例使用的发卡器:https://item.taobao.com/item.htm?ftt&id615391857885 一、读取旧Ntag卡的UID和数据 Private Sub Button15_Click(sender As Object, e As EventArgs) Handles Button15.Click轻松读卡技术支持:网站:Dim i, j As IntegerDim cardidhex, …...
多场景 OkHttpClient 管理器 - Android 网络通信解决方案
下面是一个完整的 Android 实现,展示如何创建和管理多个 OkHttpClient 实例,分别用于长连接、普通 HTTP 请求和文件下载场景。 <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas…...

Day131 | 灵神 | 回溯算法 | 子集型 子集
Day131 | 灵神 | 回溯算法 | 子集型 子集 78.子集 78. 子集 - 力扣(LeetCode) 思路: 笔者写过很多次这道题了,不想写题解了,大家看灵神讲解吧 回溯算法套路①子集型回溯【基础算法精讲 14】_哔哩哔哩_bilibili 完…...

相机从app启动流程
一、流程框架图 二、具体流程分析 1、得到cameralist和对应的静态信息 目录如下: 重点代码分析: 启动相机前,先要通过getCameraIdList获取camera的个数以及id,然后可以通过getCameraCharacteristics获取对应id camera的capabilities(静态信息)进行一些openCamera前的…...
解决本地部署 SmolVLM2 大语言模型运行 flash-attn 报错
出现的问题 安装 flash-attn 会一直卡在 build 那一步或者运行报错 解决办法 是因为你安装的 flash-attn 版本没有对应上,所以报错,到 https://github.com/Dao-AILab/flash-attention/releases 下载对应版本,cu、torch、cp 的版本一定要对…...

Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决
Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决 问题背景 在一个基于 Spring Cloud Gateway WebFlux 构建的微服务项目中,新增了一个本地验证码接口 /code,使用函数式路由(RouterFunction)和 Hutool 的 Circle…...
docker 部署发现spring.profiles.active 问题
报错: org.springframework.boot.context.config.InvalidConfigDataPropertyException: Property spring.profiles.active imported from location class path resource [application-test.yml] is invalid in a profile specific resource [origin: class path re…...