qt-C++笔记之主线程中使用异步逻辑来处理ROS事件循环和Qt事件循环解决相互阻塞的问题
qt-C++笔记之主线程中使用异步逻辑来处理ROS事件循环和Qt事件循环解决相互阻塞的问题
code review!
文章目录
- qt-C++笔记之主线程中使用异步逻辑来处理ROS事件循环和Qt事件循环解决相互阻塞的问题
- 1.Qt的app.exec()详解
- 2.ros::spin()详解
- 3.ros::AsyncSpinner详解
- 4.主线程中结合使用的示例
1.Qt的app.exec()详解
app.exec()
是Qt应用程序的主事件循环函数。它是一个阻塞函数,负责处理所有的事件和信号,并保持应用程序处于运行状态,直到退出条件满足为止。
当调用app.exec()
时,Qt会开始处理事件循环,并等待事件的触发。事件可以是来自用户的输入(例如鼠标点击、键盘按键)或其他系统事件(例如定时器事件、网络事件)。Qt会不断地从事件队列中获取事件并相应地触发对应的槽函数或事件处理函数。
在事件循环期间,Qt应用程序会保持响应,并能够实时更新UI界面。所有的UI操作和更新都应该在主线程中进行,以确保线程安全性。
只有当退出条件满足时,app.exec()
才会返回并结束应用程序的运行。在大多数情况下,退出条件是用户显式关闭应用程序的主窗口或调用QCoreApplication::quit()
函数来请求退出。
需要注意的是,app.exec()
是一个阻塞函数,它会一直运行直到应用程序退出。因此,一般情况下,应该将需要在app.exec()
之后执行的代码放置在适当的位置,或者使用信号与槽机制来处理退出时的清理操作。
总结起来,app.exec()
是Qt应用程序的主事件循环函数,负责处理事件并保持应用程序处于运行状态,直到退出条件满足。它是编写基于Qt的GUI应用程序的关键部分。
2.ros::spin()详解
ros::spin()
是ROS提供的一个阻塞函数,用于启动ROS节点的事件循环并等待节点退出的信号。它会一直运行,直到接收到终止信号或调用ros::shutdown()
函数来请求节点退出。
当调用ros::spin()
时,ROS节点会开始处理订阅者的消息、服务的请求和其他事件。它会阻塞当前线程,持续处理事件,直到满足退出条件。
ros::spin()
的主要作用是保持ROS节点处于运行状态,确保节点能够处理到来的消息和事件。它会等待消息的到达并调用对应的回调函数进行处理。如果没有消息到达,ros::spin()
会继续等待,而不会占用过多的CPU资源。
以下是使用ros::spin()
的一般流程:
- 在ROS节点初始化完成后,调用
ros::spin()
函数。 - ROS节点会开始处理订阅者的消息、服务的请求和其他事件。
- 当有消息到达时,ROS会调用对应的回调函数进行处理。
- 如果没有消息到达,
ros::spin()
会继续等待,而不会占用过多的CPU资源。 - 当接收到终止信号或调用
ros::shutdown()
函数时,ros::spin()
会退出,节点的事件循环结束。
需要注意的是,ros::spin()
是一个阻塞函数,它会一直运行直到节点退出。因此,一般情况下,应该将需要在ros::spin()
之后执行的代码放置在适当的位置,或者使用信号与槽机制来处理退出时的清理操作。
以下是使用ros::spin()
的示例代码片段:
// 初始化ROS节点
ros::init(argc, argv, "my_node");// 创建ROS节点句柄
ros::NodeHandle nh;// 创建ROS订阅者和其他对象
// ...// 启动ROS事件循环并等待节点退出
ros::spin();// 节点退出后的清理操作
// ...
总结起来,ros::spin()
是ROS提供的一个阻塞函数,用于启动ROS节点的事件循环并等待节点退出的信号。它保持节点处于运行状态,处理到来的消息和事件,并且不会占用过多的CPU资源。
3.ros::AsyncSpinner详解
ros::AsyncSpinner
是ROS提供的一个异步事件处理器,用于在单独的线程中处理ROS的回调函数和事件循环。它允许ROS节点在执行回调函数的同时继续处理其他任务,而不会被阻塞。
当创建一个ros::AsyncSpinner
对象并调用其start()
函数时,它会启动一个新的线程,并在该线程中执行ROS的事件循环。事件循环负责处理ROS的回调函数,包括订阅者的消息、服务的请求等。
使用ros::AsyncSpinner
的好处是,它允许ROS节点在单独的线程中并行处理事件,而不会阻塞主线程。这对于需要同时进行ROS通信和其他任务(例如UI更新、计算等)的应用程序特别有用。
以下是使用ros::AsyncSpinner
的一般流程:
- 创建
ros::AsyncSpinner
对象,可以设置线程数(默认为1)来指定并行处理的线程数。 - 调用
start()
函数启动异步事件循环。 - 在事件循环开始后,ROS节点会开始处理订阅者的消息、服务的请求等。
- 主线程可以继续执行其他任务,例如处理UI更新、计算等。
- 当应用程序退出时,调用
ros::AsyncSpinner
的stop()
函数来停止异步事件循环。
需要注意的是,使用ros::AsyncSpinner
时,确保在主线程中使用ros::NodeHandle
对象进行ROS通信,而不是在异步事件循环线程中使用。
以下是使用ros::AsyncSpinner
的示例代码片段:
// 创建ROS异步Spinner,指定线程数为1
ros::AsyncSpinner spinner(1);
spinner.start();// 在异步事件循环开始后执行其他任务
// ...// 停止异步事件循环
spinner.stop();
总结起来,ros::AsyncSpinner
是ROS提供的一个异步事件处理器,用于在单独的线程中处理ROS的回调函数和事件循环。它允许ROS节点在并行处理事件的同时继续执行其他任务,提高了应用程序的响应性能。
4.主线程中结合使用的示例
ros::AsyncSpinner
是ROS提供的一个类,可以在单独的线程中处理ROS的事件循环,而不会阻塞Qt的事件循环。你可以在主函数中创建一个ros::AsyncSpinner
对象,并调用其start()
函数来启动ROS事件循环。这样,ROS会在独立线程中处理事件,而主线程可以继续执行Qt的事件循环。
在这个示例中,我们在主函数中创建了一个ros::AsyncSpinner
对象spinner
,并将线程数设置为1。然后,通过调用spinner.start()
启动ROS事件循环。这样,ROS会在独立线程中处理事件,而主线程可以继续执行Qt的事件循环。
代码
#include <ros/ros.h>
#include <QApplication>
#include <QMainWindow>
#include <ros/spinner.h>
#include <std_msgs/String.h>// ROS订阅者回调函数
void rosCallback(const std_msgs::String::ConstPtr& msg)
{// 处理接收到的消息ROS_INFO("Received message: %s", msg->data.c_str());
}int main(int argc, char** argv)
{// 初始化ROS节点ros::init(argc, argv, "qt_ros_node");// 创建Qt应用程序QApplication app(argc, argv);// 创建ROS节点句柄ros::NodeHandle nh;// 创建QWidget窗口QMainWindow window;// 设置窗口大小window.resize(800, 600);// 显示窗口window.show();// 创建ROS订阅者ros::Subscriber sub = nh.subscribe("topic_name", 10, rosCallback);// 创建ROS异步Spinner,指定线程数为1ros::AsyncSpinner spinner(1);spinner.start();// 进入Qt事件循环return app.exec();
}
相关文章:

qt-C++笔记之主线程中使用异步逻辑来处理ROS事件循环和Qt事件循环解决相互阻塞的问题
qt-C笔记之主线程中使用异步逻辑来处理ROS事件循环和Qt事件循环解决相互阻塞的问题 code review! 文章目录 qt-C笔记之主线程中使用异步逻辑来处理ROS事件循环和Qt事件循环解决相互阻塞的问题1.Qt的app.exec()详解2.ros::spin()详解3.ros::AsyncSpinner详解4.主线程中结合使用…...

【Docker】从零开始:18.使用Dockerfile构造自己的KingbaseES数据库镜像
【Docker】从零开始:17.使用Dockerfile构造自己的数据库镜像 新建一个自定义目录并创建Dockerfile文件上传需要的文件到自定义目录下注意docker-circle-init.sh文件内容password 内容 开始打包注意打包完成后执行 尝试用工具连接数据库 kingbase.tar.gz 包过大我就上…...
YOLOv8独家改进《全网无重复 YOLOv8专属打造》感知聚合SERDet检测头:简单高效涨点,即插即用|检测头新颖改进
💡本篇内容:YOLOv8独家改进《全网无重复,YOLOv8专属》感知聚合SERDet检测头:高效涨点,即插即用|检测头新颖改进 💡🚀🚀🚀本博客 YOLO系列 + 全新原创感知聚合SERDet检测头 改进创新点改进源代码改进 适用于 YOLOv8 按步骤操作运行改进后的代码即可,附改进源代…...
Android Studio中Flutter项目找不到Android真机设备解决方法
起因:创建正常Android项目可以运行在真机设备上,创建flutter项目就找寻不到Android真机设备。 1:在flutter sdk安装目录按下Shift和鼠标右键,打开Powershell窗口 2:输入以下,然后回车 flutter config --…...

Vue 静态渲染 v-pre
v-pre 指令:用于阻止 Vue 解析这个标签,直接渲染到页面中。 语法格式: <div v-pre> {{ 数据 }} </div> 基础使用: <template><h3>静态渲染 v-pre</h3><p v-pre>静态渲染:{{ n…...
C语言基础概念考查备忘 - 标识符、关键字、预定义标识符、语法检查、语义检查 ... 左值、右值、对象、副作用、未定义行为、sizeof是什么等等
什么是标识符、关键字和预定义标识符?三者有何区别? 当谈论C语言中的标识符、关键字和预定义标识符时,让我们从每个概念的基础开始。 标识符(Identifiers): 标识符是用来给变量、函数、类型等命名的。在…...
插件原理与开发
插件原理与开发 在 Mybatis总体执行流程 一文中简单的介绍了插件的初始化过程,本文将从源码的角度介绍一下mybatis的插件原理与简单开发实战。 插件原理 插件的注册和管理是通过InterceptorChain进行的,在创建Executor、StatementHandler、ParameterH…...

Git 分支合并时 Merge, Rebase, Squash 的使用场景
前言 Git 的分支设计大大提升了并行开发的能力,但相应的,也就要解决如何进行分支合并。毕竟分久必合,最终还是要把大家的工作合并起来,进行统一发布的。在合并时,通常有三种操作: Merge commitsRebaseSqu…...
第5节:Vue3 JavaScript 表达式
在 Vue3 中,JavaScript 表达式的使用方式与 Vue2 有所不同。 在 Vue3 中,你可以使用 v-bind 指令来绑定 JavaScript 表达式。例如: <template><div>{{ count }}</div> </template><script> import { ref } f…...
StarRocks 存算分离最佳实践,让降本增效更简单
StarRocks 存算分离自版本 3.0.0 开放使用,已经历过多个大版本迭代,在众多客户生产环境中得到验证。但在用户使用过程中也反馈了一些问题,大多源自对新能力不够熟悉导致无法达到最佳效果。因而,本文提供 StarRocks 存算分离最佳实…...

虚拟网络技术:bond技术
网卡bond也称为网卡捆绑,就是将两个或者更多的物理网卡绑定成一个虚拟网卡。 bond的作用: 1.提高网卡的吞吐量 2.增加网络的高可用,实现负载均衡。 一、bond简介 bond技术即bonding,能将多块物理网卡绑定到一块虚拟网卡上&…...

【Android】解决安卓中并不存在ActivityMainBinding
安卓中并不存在ActivityMainBinding这个类,这个类是在XML布局的最外层加入就会自动生成。但是你在最后绑定主布局时会报错获取不到根节点getRoot(). 最好的办法就是,删除原来的最外层节点,再重新添加,感觉是因为复制时并没有让系…...

mysql的几种索引
mysql索引的介绍可以mysql官网的词汇表中搜索: https://dev.mysql.com/doc/refman/8.0/en/glossary.html mysql可以在表的一列、或者多列上创建索引,索引的类型可以选择,如下: 普通索引(KEY) 普通索引可…...

R语言手册30分钟上手
文章目录 1. 环境&安装1.1. rstudio保存工作空间 2. 创建数据集2.1. 数据集概念2.2. 向量、矩阵2.3. 数据框2.3.1. 创建数据框2.3.2. 创建新变量2.3.3. 变量的重编码2.3.4. 列重命名2.3.5. 缺失值2.3.6. 日期值2.3.7. 数据框排序2.3.8. 数据框合并(合并沪深300和中证500收盘…...

前缀和例题:子矩阵的和AcWing796-Java版
//前缀和模板提,在读入数据的时候就可以先算好前缀和的大小 //计算前缀的时候用:g[i][j] g[i][j-1] g[i-1][j] - g[i-1][j-1] Integer.parseInt(init[j-1]); //计算结果的时候用:g[x2][y2] - g[x1 - 1][y2]- g[x2][y1-1] g[x1 -1][y1 - 1] "\n" //一些重复加的地…...

前端传参中带有特殊符号导致后端接收时乱码或转码失败的解决方案
文章目录 bug背景解决思路1:解决思路2解决思路3(最终解决方案)后记 bug背景 项目中采用富文本编辑器后传参引起的bug,起因如下: 数据库中存入的数据会变成这种未经转码的URL编码 解决思路1: 使用JSON方…...
【扩散模型】深入理解图像的表示原理:从像素到张量
【扩散模型】深入理解图像的表示原理:从像素到张量 在深度学习中,图像是重要的数据源之一,而图像的表示方式对于算法的理解和处理至关重要。本文将带你深入探讨图像的底层表示原理,从像素到张量,让你对图像表示有更清…...

WPS论文写作——公式和公式序号格式化
首先新建一个表格,表格尺寸按你的需求来确定,直接 插入--》表格 即可。 然后在表格对应位置填上公式(公式要用公式编辑器)和公式序号,然后可以按照单独的单元格或者整行或整列等来设置样式,比如居中对齐、…...

ChatGPT一周年,奥特曼官宣 OpenAI 新动作!
大家好,我是二狗。 今天是11月30日,一转眼,ChatGPT 发布已经一周年了! 而就在刚刚,ChatGPT一周年之际。 OpenAI 正式宣布Sam Altman回归重任CEO, Mira Murati 重任CTO,Greg Brockman重任总裁,O…...

JVM 运行时内存篇
面试题: 讲一下为什么JVM要分为堆、方法区等?原理是什么?(UC、智联) JVM的分区了解吗,内存溢出发生在哪个位置 (亚信、BOSS) 简述各个版本内存区域的变化࿱…...

深度学习在微纳光子学中的应用
深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向: 逆向设计 通过神经网络快速预测微纳结构的光学响应,替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…...
SkyWalking 10.2.0 SWCK 配置过程
SkyWalking 10.2.0 & SWCK 配置过程 skywalking oap-server & ui 使用Docker安装在K8S集群以外,K8S集群中的微服务使用initContainer按命名空间将skywalking-java-agent注入到业务容器中。 SWCK有整套的解决方案,全安装在K8S群集中。 具体可参…...

CTF show Web 红包题第六弹
提示 1.不是SQL注入 2.需要找关键源码 思路 进入页面发现是一个登录框,很难让人不联想到SQL注入,但提示都说了不是SQL注入,所以就不往这方面想了 先查看一下网页源码,发现一段JavaScript代码,有一个关键类ctfs…...

树莓派超全系列教程文档--(61)树莓派摄像头高级使用方法
树莓派摄像头高级使用方法 配置通过调谐文件来调整相机行为 使用多个摄像头安装 libcam 和 rpicam-apps依赖关系开发包 文章来源: http://raspberry.dns8844.cn/documentation 原文网址 配置 大多数用例自动工作,无需更改相机配置。但是,一…...
c++ 面试题(1)-----深度优先搜索(DFS)实现
操作系统:ubuntu22.04 IDE:Visual Studio Code 编程语言:C11 题目描述 地上有一个 m 行 n 列的方格,从坐标 [0,0] 起始。一个机器人可以从某一格移动到上下左右四个格子,但不能进入行坐标和列坐标的数位之和大于 k 的格子。 例…...

【项目实战】通过多模态+LangGraph实现PPT生成助手
PPT自动生成系统 基于LangGraph的PPT自动生成系统,可以将Markdown文档自动转换为PPT演示文稿。 功能特点 Markdown解析:自动解析Markdown文档结构PPT模板分析:分析PPT模板的布局和风格智能布局决策:匹配内容与合适的PPT布局自动…...

WordPress插件:AI多语言写作与智能配图、免费AI模型、SEO文章生成
厌倦手动写WordPress文章?AI自动生成,效率提升10倍! 支持多语言、自动配图、定时发布,让内容创作更轻松! AI内容生成 → 不想每天写文章?AI一键生成高质量内容!多语言支持 → 跨境电商必备&am…...

学习STC51单片机32(芯片为STC89C52RCRC)OLED显示屏2
每日一言 今天的每一份坚持,都是在为未来积攒底气。 案例:OLED显示一个A 这边观察到一个点,怎么雪花了就是都是乱七八糟的占满了屏幕。。 解释 : 如果代码里信号切换太快(比如 SDA 刚变,SCL 立刻变&#…...
Web 架构之 CDN 加速原理与落地实践
文章目录 一、思维导图二、正文内容(一)CDN 基础概念1. 定义2. 组成部分 (二)CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 (三)CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 …...

九天毕昇深度学习平台 | 如何安装库?
pip install 库名 -i https://pypi.tuna.tsinghua.edu.cn/simple --user 举个例子: 报错 ModuleNotFoundError: No module named torch 那么我需要安装 torch pip install torch -i https://pypi.tuna.tsinghua.edu.cn/simple --user pip install 库名&#x…...