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

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()的一般流程:

  1. 在ROS节点初始化完成后,调用ros::spin()函数。
  2. ROS节点会开始处理订阅者的消息、服务的请求和其他事件。
  3. 当有消息到达时,ROS会调用对应的回调函数进行处理。
  4. 如果没有消息到达,ros::spin()会继续等待,而不会占用过多的CPU资源。
  5. 当接收到终止信号或调用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的一般流程:

  1. 创建ros::AsyncSpinner对象,可以设置线程数(默认为1)来指定并行处理的线程数。
  2. 调用start()函数启动异步事件循环。
  3. 在事件循环开始后,ROS节点会开始处理订阅者的消息、服务的请求等。
  4. 主线程可以继续执行其他任务,例如处理UI更新、计算等。
  5. 当应用程序退出时,调用ros::AsyncSpinnerstop()函数来停止异步事件循环。

需要注意的是,使用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】从零开始&#xff1a;17.使用Dockerfile构造自己的数据库镜像 新建一个自定义目录并创建Dockerfile文件上传需要的文件到自定义目录下注意docker-circle-init.sh文件内容password 内容 开始打包注意打包完成后执行 尝试用工具连接数据库 kingbase.tar.gz 包过大我就上…...

YOLOv8独家改进《全网无重复 YOLOv8专属打造》感知聚合SERDet检测头:简单高效涨点,即插即用|检测头新颖改进

💡本篇内容:YOLOv8独家改进《全网无重复,YOLOv8专属》感知聚合SERDet检测头:高效涨点,即插即用|检测头新颖改进 💡🚀🚀🚀本博客 YOLO系列 + 全新原创感知聚合SERDet检测头 改进创新点改进源代码改进 适用于 YOLOv8 按步骤操作运行改进后的代码即可,附改进源代…...

Android Studio中Flutter项目找不到Android真机设备解决方法

起因&#xff1a;创建正常Android项目可以运行在真机设备上&#xff0c;创建flutter项目就找寻不到Android真机设备。 1&#xff1a;在flutter sdk安装目录按下Shift和鼠标右键&#xff0c;打开Powershell窗口 2&#xff1a;输入以下&#xff0c;然后回车 flutter config --…...

Vue 静态渲染 v-pre

v-pre 指令&#xff1a;用于阻止 Vue 解析这个标签&#xff0c;直接渲染到页面中。 语法格式&#xff1a; <div v-pre> {{ 数据 }} </div> 基础使用&#xff1a; <template><h3>静态渲染 v-pre</h3><p v-pre>静态渲染&#xff1a;{{ n…...

C语言基础概念考查备忘 - 标识符、关键字、预定义标识符、语法检查、语义检查 ... 左值、右值、对象、副作用、未定义行为、sizeof是什么等等

什么是标识符、关键字和预定义标识符&#xff1f;三者有何区别&#xff1f; 当谈论C语言中的标识符、关键字和预定义标识符时&#xff0c;让我们从每个概念的基础开始。 标识符&#xff08;Identifiers&#xff09;&#xff1a; 标识符是用来给变量、函数、类型等命名的。在…...

插件原理与开发

插件原理与开发 在 Mybatis总体执行流程 一文中简单的介绍了插件的初始化过程&#xff0c;本文将从源码的角度介绍一下mybatis的插件原理与简单开发实战。 插件原理 插件的注册和管理是通过InterceptorChain进行的&#xff0c;在创建Executor、StatementHandler、ParameterH…...

Git 分支合并时 Merge, Rebase, Squash 的使用场景

前言 Git 的分支设计大大提升了并行开发的能力&#xff0c;但相应的&#xff0c;也就要解决如何进行分支合并。毕竟分久必合&#xff0c;最终还是要把大家的工作合并起来&#xff0c;进行统一发布的。在合并时&#xff0c;通常有三种操作&#xff1a; Merge commitsRebaseSqu…...

第5节:Vue3 JavaScript 表达式

在 Vue3 中&#xff0c;JavaScript 表达式的使用方式与 Vue2 有所不同。 在 Vue3 中&#xff0c;你可以使用 v-bind 指令来绑定 JavaScript 表达式。例如&#xff1a; <template><div>{{ count }}</div> </template><script> import { ref } f…...

StarRocks 存算分离最佳实践,让降本增效更简单

StarRocks 存算分离自版本 3.0.0 开放使用&#xff0c;已经历过多个大版本迭代&#xff0c;在众多客户生产环境中得到验证。但在用户使用过程中也反馈了一些问题&#xff0c;大多源自对新能力不够熟悉导致无法达到最佳效果。因而&#xff0c;本文提供 StarRocks 存算分离最佳实…...

虚拟网络技术:bond技术

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

【Android】解决安卓中并不存在ActivityMainBinding

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

mysql的几种索引

mysql索引的介绍可以mysql官网的词汇表中搜索&#xff1a; https://dev.mysql.com/doc/refman/8.0/en/glossary.html mysql可以在表的一列、或者多列上创建索引&#xff0c;索引的类型可以选择&#xff0c;如下&#xff1a; 普通索引&#xff08;KEY&#xff09; 普通索引可…...

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&#xff1a;解决思路2解决思路3&#xff08;最终解决方案&#xff09;后记 bug背景 项目中采用富文本编辑器后传参引起的bug&#xff0c;起因如下&#xff1a; 数据库中存入的数据会变成这种未经转码的URL编码 解决思路1&#xff1a; 使用JSON方…...

【扩散模型】深入理解图像的表示原理:从像素到张量

【扩散模型】深入理解图像的表示原理&#xff1a;从像素到张量 在深度学习中&#xff0c;图像是重要的数据源之一&#xff0c;而图像的表示方式对于算法的理解和处理至关重要。本文将带你深入探讨图像的底层表示原理&#xff0c;从像素到张量&#xff0c;让你对图像表示有更清…...

WPS论文写作——公式和公式序号格式化

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

ChatGPT一周年,奥特曼官宣 OpenAI 新动作!

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

JVM 运行时内存篇

面试题&#xff1a; 讲一下为什么JVM要分为堆、方法区等&#xff1f;原理是什么&#xff1f;&#xff08;UC、智联&#xff09; JVM的分区了解吗&#xff0c;内存溢出发生在哪个位置 &#xff08;亚信、BOSS&#xff09; 简述各个版本内存区域的变化&#xff1…...

多模态2025:技术路线“神仙打架”,视频生成冲上云霄

文&#xff5c;魏琳华 编&#xff5c;王一粟 一场大会&#xff0c;聚集了中国多模态大模型的“半壁江山”。 智源大会2025为期两天的论坛中&#xff0c;汇集了学界、创业公司和大厂等三方的热门选手&#xff0c;关于多模态的集中讨论达到了前所未有的热度。其中&#xff0c;…...

ssc377d修改flash分区大小

1、flash的分区默认分配16M、 / # df -h Filesystem Size Used Available Use% Mounted on /dev/root 1.9M 1.9M 0 100% / /dev/mtdblock4 3.0M...

多模态图像修复系统:基于深度学习的图片修复实现

多模态图像修复系统:基于深度学习的图片修复实现 1. 系统概述 本系统使用多模态大模型(Stable Diffusion Inpainting)实现图像修复功能,结合文本描述和图片输入,对指定区域进行内容修复。系统包含完整的数据处理、模型训练、推理部署流程。 import torch import numpy …...

MacOS下Homebrew国内镜像加速指南(2025最新国内镜像加速)

macos brew国内镜像加速方法 brew install 加速formula.jws.json下载慢加速 &#x1f37a; 最新版brew安装慢到怀疑人生&#xff1f;别怕&#xff0c;教你轻松起飞&#xff01; 最近Homebrew更新至最新版&#xff0c;每次执行 brew 命令时都会自动从官方地址 https://formulae.…...

【前端异常】JavaScript错误处理:分析 Uncaught (in promise) error

在前端开发中&#xff0c;JavaScript 异常是不可避免的。随着现代前端应用越来越多地使用异步操作&#xff08;如 Promise、async/await 等&#xff09;&#xff0c;开发者常常会遇到 Uncaught (in promise) error 错误。这个错误是由于未正确处理 Promise 的拒绝&#xff08;r…...

Chrome 浏览器前端与客户端双向通信实战

Chrome 前端&#xff08;即页面 JS / Web UI&#xff09;与客户端&#xff08;C 后端&#xff09;的交互机制&#xff0c;是 Chromium 架构中非常核心的一环。下面我将按常见场景&#xff0c;从通道、流程、技术栈几个角度做一套完整的分析&#xff0c;特别适合你这种在分析和改…...

深度剖析 DeepSeek 开源模型部署与应用:策略、权衡与未来走向

在人工智能技术呈指数级发展的当下&#xff0c;大模型已然成为推动各行业变革的核心驱动力。DeepSeek 开源模型以其卓越的性能和灵活的开源特性&#xff0c;吸引了众多企业与开发者的目光。如何高效且合理地部署与运用 DeepSeek 模型&#xff0c;成为释放其巨大潜力的关键所在&…...

使用SSE解决获取状态不一致问题

使用SSE解决获取状态不一致问题 1. 问题描述2. SSE介绍2.1 SSE 的工作原理2.2 SSE 的事件格式规范2.3 SSE与其他技术对比2.4 SSE 的优缺点 3. 实战代码 1. 问题描述 目前做的一个功能是上传多个文件&#xff0c;这个上传文件是整体功能的一部分&#xff0c;文件在上传的过程中…...

密码学基础——SM4算法

博客主页&#xff1a;christine-rr-CSDN博客 ​​​​专栏主页&#xff1a;密码学 &#x1f4cc; 【今日更新】&#x1f4cc; 对称密码算法——SM4 目录 一、国密SM系列算法概述 二、SM4算法 2.1算法背景 2.2算法特点 2.3 基本部件 2.3.1 S盒 2.3.2 非线性变换 ​编辑…...

Redis上篇--知识点总结

Redis上篇–解析 本文大部分知识整理自网上&#xff0c;在正文结束后都会附上参考地址。如果想要深入或者详细学习可以通过文末链接跳转学习。 1. 基本介绍 Redis 是一个开源的、高性能的 内存键值数据库&#xff0c;Redis 的键值对中的 key 就是字符串对象&#xff0c;而 val…...