Qt之postEvent

基本介绍

postEvent方法所属类为QCoreApplication,完整声明如下:

[static] void QCoreApplication::postEvent(QObject *receiver, QEvent *event, int priority = Qt::NormalEventPriority)

该方法的作用是将要发送的事件推送到对应线程的事件队列中,用于后续的事件循环(关于事件循环相关内容,请到本专栏中对应文章中去看)。

理解

该如何理解这个方法呢?我个人的理解是首先认识到这一个异步非阻塞的调用,说它异步是因为调用这个函数后,要发送的事件并没有立即推送给接收对象(receiver)进行处理,而是将其推送到事件队列,这个事件队列来自谁呢?事件队列是基于线程的,一个线程只有一个事件队列虽然可以启动多个事件循环,但是一个线程下的所有事件循环共享同一个事件调度器,一个事件调度器仅有一个事件队列。说他非阻塞是说将事件加入到事件队列后,立即返回,并不会造成调用者阻塞。一般用于跨线程之间的事件推送,比如线程A的对象a要发送一个事件到线程B的对象b,要使用该方法完成这个功能。

源码分析

post源码核心功能代码如下:

void QCoreApplication::postEvent(QObject *receiver, QEvent *event, int priority)
{……QThreadData * volatile * pdata = &receiver->d_func()->threadData;QThreadData *data = *pdata;……data->postEventList.addEvent(QPostEvent(receiver, event, priority));……QAbstractEventDispatcher* dispatcher = data->eventDispatcher.loadAcquire();if (dispatcher)dispatcher->wakeUp();
}

通过上面的代码可以看到,data表示的一个对象的threadData(线程数据),其成员postEventList表示的是事件队列,AddEvent通过字面意思就能理解,即将事件加入到事件队列中。然后调用事件调度器的wakeup方法唤醒对应线程,通知器事件队列有了新数据,可以进行事件循环了,从这个角度理解,该操作可以防止程序死循环,满负荷运转。wakeup的方法如下:

void QEventDispatcherUNIX::wakeUp()
{Q_D(QEventDispatcherUNIX);d->threadPipe.wakeUp();
}void QThreadPipe::wakeUp()
{if (wakeUps.testAndSetAcquire(0, 1)) {
#ifndef QT_NO_EVENTFDif (fds[1] == -1) {// eventfdeventfd_t value = 1;int ret;EINTR_LOOP(ret, eventfd_write(fds[0], value));return;}
#endifchar c = 0;qt_safe_write(fds[1], &c, 1);}
}

有兴趣的朋友可以研究一下上面这部分代码,这里设计了QThreadPipe,这个类的作用我没有看明白,后续有时间研究一下,而且涉及了到了eventfd系统调用,该调用后续我再研究一下。

使用注意事项

  • 本方法属于异步调用,将要发布的事件添加到线程中事件调度器的事件队列中,调用后立即返回。
  • 调用本方法中的event参数为一个指针,该指针必须通过new申请,并且该对象的释放由该方法内部完成,用户无需单独释放该内存。
  • 该方式是一个静态方法,使用方法如下
QCoreApplication::postEvent(receive,event)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/74594.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于SpringBoot的在线教育平台系统

基于SpringBootVue的线教育平台系统,前后端分离 开发语言:Java数据库:MySQL技术:SpringBoot、Vue、Mybaits Plus、ELementUI工具:IDEA/Ecilpse、Navicat、Maven 【主要功能】 角色:管理员、学生、老师 …

【网络编程】学习成果day7:用sqlite3和fgetc将字典写入数据库中的数据表。

1.将字典写入数据库中的数据表 代码&#xff1a; linuxlinux:~/study/NETbc$ cat 03_dictsqlite3.c #include<myhead.h> #define MAX 50int do_insert(sqlite3* db);int main(int argc, const char *argv[]) {//打开数据库sqlite3 *dbNULL;if(sqlite3_open("./dic…

修改Docker的运行时数据存储位置

Docker的运行时数据&#xff0c;包括镜像、容器、网络和存储卷等默认存储在/var/lib/docker目录下&#xff0c;如果硬盘容量有限我们则需要修改这个存储位置 修改步骤如下&#xff1a; 停止Docker服务&#xff1a;sudo systemctl stop docker 创建一个新的目录来存储Docker运…

【C++基础】5. 常量

文章目录 【 1. 常量的分类 】1.1 整型常量1.2 浮点常量1.3 字符常量1.4 字符串常量1.5 布尔常量 【 2. 常量的定义 】2.1 #define 预处理器2.2 const 关键字 常量 是固定值&#xff0c;在程序执行期间不会改变。这些固定的值&#xff0c;又叫做字面量。常量可以是任何的基本数…

企业架构LNMP学习笔记22

防盗链原理和实现。 域名A的资源文件&#xff0c;经常被域名B直接调用访问。 而用户经常访问域名B&#xff0c;看到的资源&#xff08;图片等&#xff09;以为是域名B的&#xff0c;实际则是域名A的。 但是域名A没有获得任何收益&#xff0c;却要给域名B来源的访问消耗服务器…

总结 - 组件通用封装思路(组件封装)

组件封装&#xff1a; 1. 不变&#xff1b; 2. 变&#xff1a;①prop ②slot插槽 详细总结在文末。 --------------------------------------------------------------------------------------------------- 问题&#xff1a;结构相似&#xff0c;内容不同 --》 可以用组…

在Kubernetes环境中有关Nginx Ingress与API Gateway的连接问题

文章目录 小结问题解决参考 小结 在Kubernetes环境中是通过Nginx Ingress来从外部访问Kubernetes内部的环境&#xff0c;并用API Gateway来分发请求&#xff0c;碰到了 502 Bad gateway.的问题&#xff0c;并尝试解决。 问题 从外部通过Nginx Ingress访问Kubernetes内部的环…

Shell命令管理进程

Shell命令管理进程 列出进程 ps命令 top命令 管理后台进程 启动后台进程 查看后台进程 jobs和ps的区别 停止进程 Linux除了是一种多用户操作系统之外&#xff0c;还是一种多任务系统。多任务意味着可以同时运行多个程序。Linux 提供了相关的工具来列出运行中的进程,监视…

ClickHouse进阶(七):Clickhouse数据查询-1

进入正文前&#xff0c;感谢宝子们订阅专题、点赞、评论、收藏&#xff01;关注IT贫道&#xff0c;获取高质量博客内容&#xff01; &#x1f3e1;个人主页&#xff1a;含各种IT体系技术,IT贫道_Apache Doris,大数据OLAP体系技术栈,Kerberos安全认证-CSDN博客 &#x1f4cc;订阅…

SpringMVC应用

文章目录 一、常用注解二、参数传递2.1 基础类型String2.2 复杂类型2.3 RequestParam2.4.路径传参 PathVariable2.4 Json数据传参 RequestBody2.5 RequestHeader 三、方法返回值3.1 void3.2 Stringmodel3.3 ModelAndView 一、常用注解 SpringMVC是一个基于Java的Web框架&#…

11.Redis的慢操作之rehash

Redis为什么快 它接收到一个键值对操作后&#xff0c;能以微秒级别的速度找到数据&#xff0c;并快速完成操作。 数据库这么多&#xff0c;为啥 Redis 能有这么突出的表现呢&#xff1f; 内存数据结构 一方面&#xff0c;这是因为它是内存数据库&#xff0c;所有操作都在内存上…

查看mysql数据库的charset和collation

SELECT * FROM information_schema.SCHEMATA WHERE schema_name test_data; 发现&#xff1a; chaset是utf8mb4&#xff0c;collation是utf8mb4_generic_ci 可笑的是我导入sql脚本&#xff0c;要把脚本中所有的utf8mb4改为utf8&#xff0c;将utf8mb4_generic_ci为utf8_unico…

React 开发一个移动端项目(1)

技术栈&#xff1a; 项目搭建&#xff1a;React 官方脚手架 create-react-appreact hooks状态管理&#xff1a;redux 、 redux-thunkUI 组件库&#xff1a;antd-mobileajax请求库&#xff1a;axios路由&#xff1a;react-router-dom 以及 historyCSS 预编译器&#xff1a;sass…

Qt版本的冷知识

Qt4.8.7是Qt4的终结版本&#xff0c;是Qt4系列版本中最稳定最经典的&#xff08;很多嵌入式板子还是用Qt4.8&#xff09;&#xff0c;其实该版本是和Qt5.5差不多时间发布的。参考链接 https://www.qt.io/blog/2015/05/26/qt-4-8-7-released https://blog.qt.io/blog/2015/07/01…

SpringBoot 拦截org.thymeleaf.exceptions.TemplateInputException异常

SpringBoot 拦截thymeleaf异常 org.thymeleaf.exceptions.TemplateInputException异常 org.thymeleaf.exceptions.TemplateProcessingE xception: Could not parse as each: "message : xxx " (template: “xxxx” - line xx, col xx) thymeleaf异常复现 你是故意的…

Vue3,Typescript中引用组件路径无法找到模块报错

是这么个事&#xff0c;我在vue3新创建的项目里&#xff0c;写了个组件叫headerIndex.vue&#xff0c;放到app.vue中import就会报错 路径肯定没写错&#xff0c;找到了解决方法&#xff0c;但是也没想明白为什么 解决方法如下 在vite-env.d.ts文件中加入 declare module &qu…

内网隧道代理技术(二十三)之 DNS隧道反弹Shell

DNS隧道反弹Shell DNS隧道 DNS协议是一种请求、应答协议,也是一种可用于应用层的隧道技术。DNS隧道的工作原理很简单,在进行DNS查询时,如果查询的域名不在DNS服务器本机缓存中,就会访问互联网进行查询,然后返回结果。如果在互联网上有一台定制的服务器,那么依靠DNS协议…

Vue进阶(贰幺幺)CVE-2020-11022/CVE-2020-11023漏洞解析

文章目录 一、前言二、漏洞原理三、修复方案3.1 升级jQuery3.2 1.x 升级至 3.x 需要考虑的问题3.2.1 table表格元素自动添加tbody3.2.2 方法变更 3.3 jquery migrate是什么 四、拓展阅读 一、前言 代码安全扫描阶段&#xff0c;前端资源审计发现jQuery版本过低导致生产系统存在…

Spring MVC Http Event Stream

什么是 Http Event Stream Event Stream 技术是一种实现服务器推送事件的方法&#xff0c;它通过在一个持续的 HTTP 连接上发送事件流来实现推送。具体来说&#xff0c;服务器发送一些事件到客户端&#xff0c;并将这些事件封装成一些指定格式的文本流。客户端通过监听这个流&…

(二十六)大数据实战——kafka集群之Kraft模式安装与部署

前言 本节内容主要介绍kafka3.0版本以后&#xff0c;一种新的kafka集群搭建模式看kraft&#xff0c;在该模式下&#xff0c;kafka高可用不在依赖于zookeeper&#xff0c;用 controller 节点代替 zookeeper&#xff0c;元数据保存在 controller 中&#xff0c;由 controller 直…