QT中QTimer的循环时间小于槽函数执行时间时的状况分析

news2024/11/26 10:40:43

目录

QTimer运行程序在控制台中实现: 

当循环间隔时间大于槽函数时间时:

当存在两个定时器器,其中一个还是间隔100ms,另一个间隔1000ms: 

当两个定时器的循环周期大于槽函数执行时间时


QTimer运行程序在控制台中实现: 

#include <QtCore/QCoreApplication>
#include <QTimer>
#include <QThread>
#include <iostream>
#include <QObject>
#include <QTime>

void timer1()
{
    std::cout << QTime::currentTime().toString("HH:mm:ss zzz").toStdString() <<"  1" << std::endl;
    QThread::msleep(1000);
    std::cout << QTime::currentTime().toString("HH:mm:ss zzz").toStdString() <<"  2" << std::endl;
    QThread::msleep(1000);
    std::cout << QTime::currentTime().toString("HH:mm:ss zzz").toStdString() <<"  3" << std::endl;
    QThread::msleep(1000);
	std::cout << QTime::currentTime().toString("HH:mm:ss zzz").toStdString() <<"  4" << std::endl;
	QThread::msleep(1000);
	std::cout << QTime::currentTime().toString("HH:mm:ss zzz").toStdString() <<"  5" << std::endl;
	QThread::msleep(1000);
	std::cout << QTime::currentTime().toString("HH:mm:ss zzz").toStdString() <<"  6" << std::endl;
}


int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    QTimer timeTest;
    timeTest.setTimerType(Qt::PreciseTimer);
    QObject::connect(&timeTest, &QTimer::timeout, [=]() {timer1(); });
    
    timeTest.start(100);

    return a.exec();
}

执行结果: 

结果分析:

QTimer 设置的循环时间小于槽函数的执行时间时,当循环时间结束时,并不会将槽函数中断,而是等槽函数运行结束后,直接再次进入,中间没有间隔时间。

当循环间隔时间大于槽函数时间时:

#include <QtCore/QCoreApplication>
#include <QTimer>
#include <QThread>
#include <iostream>
#include <QObject>
#include <QTime>

void timer1()
{
    std::cout << QTime::currentTime().toString("HH:mm:ss zzz").toStdString() <<"  1" << std::endl;
    QThread::msleep(1000);
    std::cout << QTime::currentTime().toString("HH:mm:ss zzz").toStdString() <<"  2" << std::endl;
    QThread::msleep(1000);
    std::cout << QTime::currentTime().toString("HH:mm:ss zzz").toStdString() <<"  3" << std::endl;
    QThread::msleep(1000);
	std::cout << QTime::currentTime().toString("HH:mm:ss zzz").toStdString() <<"  4" << std::endl;
	QThread::msleep(1000);
	std::cout << QTime::currentTime().toString("HH:mm:ss zzz").toStdString() <<"  5" << std::endl;
	QThread::msleep(1000);
	std::cout << QTime::currentTime().toString("HH:mm:ss zzz").toStdString() <<"  6" << std::endl;
}


int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    QTimer timeTest;
    timeTest.setTimerType(Qt::PreciseTimer);
    QObject::connect(&timeTest, &QTimer::timeout, [=]() {timer1(); });
    
    timeTest.start(7000);

    return a.exec();
}

 结果分析:

间隔时间都比较准。每次的间隔时间也不会存在累计误差。

当存在两个定时器器,其中一个还是间隔100ms,另一个间隔1000ms: 

#include <QtCore/QCoreApplication>
#include <QTimer>
#include <QThread>
#include <iostream>
#include <QObject>
#include <QTime>

void timer1()
{
    std::cout << QTime::currentTime().toString("HH:mm:ss zzz").toStdString() <<"  1" << std::endl;
    QThread::msleep(1000);
    std::cout << QTime::currentTime().toString("HH:mm:ss zzz").toStdString() <<"  2" << std::endl;
    QThread::msleep(1000);
    std::cout << QTime::currentTime().toString("HH:mm:ss zzz").toStdString() <<"  3" << std::endl;
    QThread::msleep(1000);
	std::cout << QTime::currentTime().toString("HH:mm:ss zzz").toStdString() <<"  4" << std::endl;
	QThread::msleep(1000);
	std::cout << QTime::currentTime().toString("HH:mm:ss zzz").toStdString() <<"  5" << std::endl;
	QThread::msleep(1000);
	std::cout << QTime::currentTime().toString("HH:mm:ss zzz").toStdString() <<"  6" << std::endl;
}

void timer2()
{
	std::cout << QTime::currentTime().toString("HH:mm:ss zzz").toStdString() << "  Timer2" << std::endl;
	//QThread::msleep(1000);
}
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    QTimer timeTest,timeTest2;
    timeTest.setTimerType(Qt::PreciseTimer);
    timeTest2.setTimerType(Qt::PreciseTimer);
    QObject::connect(&timeTest, &QTimer::timeout, [=]() {timer1(); });
    QObject::connect(&timeTest2, &QTimer::timeout, [=]() {timer2(); });

    timeTest.start(100);
    timeTest2.start(1000);
    return a.exec();
}

结果分析:

第一个100ms的定时器优先抢占触发事件,当执行完两个对应槽函数后,第二个1000ms的定时器才执行一次槽函数。 

100ms触发

1s-2s-3s-4s-5s-6s-1s-2s-3s-4s-5s-6s-第二个触发-

总结:在不能确定定时器槽函数执行时间时,如果还存在其他定时器,当第一个定时器执行超时时,将直接影响第二个定时器的执行周期。所以在这种应用中,尽量避免定时器的循环周期小于槽函数执行时长。

当两个定时器的循环周期大于槽函数执行时间时

#include <QtCore/QCoreApplication>
#include <QTimer>
#include <QThread>
#include <iostream>
#include <QObject>
#include <QTime>

void timer1()
{
    std::cout << QTime::currentTime().toString("HH:mm:ss zzz").toStdString() <<"  1" << std::endl;
    QThread::msleep(1000);
    std::cout << QTime::currentTime().toString("HH:mm:ss zzz").toStdString() <<"  2" << std::endl;
    QThread::msleep(1000);
    std::cout << QTime::currentTime().toString("HH:mm:ss zzz").toStdString() <<"  3" << std::endl;
    QThread::msleep(1000);
	std::cout << QTime::currentTime().toString("HH:mm:ss zzz").toStdString() <<"  4" << std::endl;
	QThread::msleep(1000);
	std::cout << QTime::currentTime().toString("HH:mm:ss zzz").toStdString() <<"  5" << std::endl;
	QThread::msleep(1000);
	std::cout << QTime::currentTime().toString("HH:mm:ss zzz").toStdString() <<"  6" << std::endl;
}

void timer2()
{
	std::cout << QTime::currentTime().toString("HH:mm:ss zzz").toStdString() << "  Timer2" << std::endl;
	//QThread::msleep(1000);
}
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    QTimer timeTest,timeTest2;
    timeTest.setTimerType(Qt::PreciseTimer);
    timeTest2.setTimerType(Qt::PreciseTimer);
    QObject::connect(&timeTest, &QTimer::timeout, [=]() {timer1(); });
    QObject::connect(&timeTest2, &QTimer::timeout, [=]() {timer2(); });

    timeTest2.start(1000);
    timeTest.start(7000);
   
    return a.exec();
}

结果分析:

当两个定时器在同一个线程中时,两个定时器是按单线程串行的方式执行,当其中一个定时器触发时,必须等待当前定时器执行完成后,才有可能执行另外的定时器,两个定时器的优先级感觉是随机的。这也就解释了为什么上个案例定时周期不稳定的原因。

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

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

相关文章

工作笔记20230717

1、C#中winform页面增加切换页面 2、单独定义struct的时候要用变量赋值 using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Runtime.InteropServices; using System.Runtime.Serialization; using System.Text; usi…

xml.etree.ElementTree

python使用 xml.etree.ElementTree包的时候&#xff0c;对xml中的空标签进行了简写&#xff0c;想恢复成正常模式怎么弄

如何实现服务器对外开放?路由器端口映射怎么设置?

使用路由器后&#xff0c;Internet用户无法访问到局域网内的主机&#xff0c;因此不能访问内网搭建的Web、FTP、Mail等服务器。路由器端口映射功能可以实现将内网的服务器映射到Internet&#xff0c;从而实现服务器对外开放。路由器端口映射怎么设置&#xff1f;下面给大家介绍…

代码随想录算法训练营第二十天 | 动态规划系列9,10,11,12

动态规划系列9,10,11,12 300 最长递增子序列未看解答自己编写的青春版重点代码随想录的代码我的代码(当天晚上理解后自己编写) 674 最长连续递增序列未看解答自己编写的青春版重点代码随想录的代码我的代码(当天晚上理解后自己编写) 718 最长重复子数组未看解答自己编写的青春版…

ETHERNET/IP转TCP/IP网关tcp/ip协议包含哪几层

大家好&#xff0c;今天我们将带大家了解一款自主研发的通讯网关&#xff0c;远创智控YC-EIP-TCP/IP。这是一个强大的工具&#xff0c;能帮助我们将ETHERNET/IP网络和TCP/IP网络连接在一起&#xff0c;让我们更好地管理和监控网络。 1, 首先&#xff0c;让我们来看看这款网关…

时序数据库 TDengine 流式计算在吉科软冷链系统中的应用实践

当下&#xff0c;随着物流供应链的不断发展&#xff0c;冷链物流正变得越来越重要。通过数字化、平台化和生态化的智慧冷链监管平台&#xff0c;企业可以更好地掌握运输车辆的位置&#xff0c;及时发现并处理异常事件&#xff0c;有效提升客户满意度和信任度&#xff0c;同时也…

轻松构建业务应用程序,提高效率和准确性

在数字化时代&#xff0c;企业和组织面临着不断增长的业务需求和快速变化的市场环境。为了适应这一挑战&#xff0c;越来越多的企业开始寻找一种能够快速开发应用程序、提高效率并降低成本的解决方案。在众多的选项中&#xff0c;我们聊一聊中小企业可选择的低代码平台。 一、简…

idea创建spark教程

1、环境准备 java -version scala -version mvn -version spark -version 2、创建spark项目 创建spark项目&#xff0c;有两种方式&#xff1b;一种是本地搭建hadoop和spark环境&#xff0c;另一种是下载maven依赖&#xff1b;最后在idea中进行配置&#xff0c;下面分别记录两…

2024考研408-操作系统 第四章-文件管理 学习笔记

文章目录 一、文件系统基础1.1、初识文件管理1.1.文件的属性1.1.2、文件内部的数据应该怎样组织起来&#xff08;无结构与有结构&#xff09;1.1.3、文件之间应该怎样组织起来&#xff1f;1.1.4、操作系统应该向上提供哪些功能&#xff1f;1.1.5、从上往下看&#xff0c;文件应…

【监控系统】Promethus监控SpringBoot微服务应用配置实战

我们本节要实现的是Java服务级监控用于对每个应用占用的内存、线程池的线程数量、restful调用数量和响应时间、JVM状态、GC信息等进行监控&#xff0c;并可将指标信息同步至Prometheus中集中展示和报警。 首先我们先了解下什么是actuator&#xff1f; Spring Boot Actuator 模…

从头开始:自定义类型入门指南(结构体、位段、枚举、联合)

目录 文章目录 前言 结构体 结构体类型的声明 结构体的自引用 结构体变量的定义和初始化 结构体变量定义 初始化 结构体大小 结构体传参 位段 什么是位段 枚举 枚举的定义 枚举的优点 枚举的使用 联合&#xff08;共用体&#xff09; 联合类型的定义 联合大小的计算 总结 前…

基于Nginx的web集群项目

目录 nginx介绍代理集群 安装配置文件http 使用master和worker升级问题 基于域名的虚拟主机隐藏nginx的版本信息供别人下载的网站统计的信息的页面pv介绍 ngixn续nginx认证nginx的allow和denynginx限制并发数nginx限速限速的算法 nginx 限制请求数nginx 的 locationnginx 的 lo…

代码随想录算法训练营day4 | 24. 两两交换链表中的节点,19. 删除链表的倒数第 N 个结点,面试题 02.07. 链表相交,142. 环形链表 II

目录 24. 两两交换链表中的节点 19. 删除链表的倒数第 N 个结点 面试题 02.07. 链表相交 142. 环形链表 II 24. 两两交换链表中的节点 24. 两两交换链表中的节点 难度&#xff1a;medium 类型&#xff1a;链表 思路&#xff1a; 代码&#xff1a; class Solution {pub…

【目标检测】ROI Polling和ROI Align

ROI Pooling和ROI Align都是为了解决目标检测RPN任务后得到的一系列proposals大小不一致的问题。 ✨ 1 基本思想 &#x1f30a; 1.1 ROI Pooling 假设有一张特征图大小为8x8(原图大小sxs)&#xff0c;一个bbox坐标(0, 3, 7, 8)&#xff0c;我们目标是获得大小为2x2的特征图作…

PostgreSQL 考试认证指南:考前准备和考试概述

下面是关于考前准备和考试概述的指南&#xff1a; 考前准备&#xff1a; 1.确定考试内容&#xff1a;详细了解考试的内容范围和考试要求。可以查阅PostgreSQL官方网站或认证考试指南&#xff0c;以获取相关信息。 2.学习和实践&#xff1a;系统地学习和掌握与PostgreSQL相关…

Animboat Application Framework

SpringBoot的服务将部署在云端 管理云端数据和处理分布式的业务请求 本地基础服务将作为云端和终端中间媒介&#xff0c; 与局域网内其它dcc 插件或者app运行实例进行通信&#xff0c; 同时本地基础服务将负责本地数据的管理。 每个AppInstance都会有自己的FlaskSvr用于与Loc…

前端学习记录~2023.7.16~CSS杂记 Day8

前言一、正常布局流二、弹性盒子1、为什么是弹性盒子2、指定元素的布局为flexible3、flex 模型说明4、列还是行&#xff1f;5、换行6、flex-flow 缩写7、flex 项的动态尺寸8、flex&#xff1a;缩写与全写9、水平和垂直对齐&#xff08;1&#xff09;align-items 属性&#xff0…

[极客大挑战 2019]PHP(反序列化)

介绍说明&#xff0c;有备份的习惯&#xff0c;找常见的备份文件后缀名 使用dirsearch进行扫描 dirsearch -u http://f64378a5-a3e0-4dbb-83a3-990bb9e19901.node4.buuoj.cn:81/ -e php-e 指定网站语言 扫描出现&#xff0c;www.zip文件 查看index.php <?php include c…

C\C++ 使用socket判断ip是否能连通

文章作者&#xff1a;里海 来源网站&#xff1a;https://blog.csdn.net/WangPaiFeiXingYuan 简介&#xff1a; 使用socket判断ip是否能联通 效果&#xff1a; 代码&#xff1a; #include <iostream> #include <cstdlib> #include <cstdio> #include &…

Openlayers实战:加载GPX文件

在OPenlayers的交互中,经常性的我们要加载一些数据,在这个实战中,演示的是加载GPX文件。 GPX(GPS eXchange Format,GPS交换格式)是一个XML格式,为应用软件设计的通用GPS数据格式。它可以用来描述路点、轨迹、路程。这个格式是免费的,可以在不需要付任何许可费用的前提…