Qt Sleep、QCoreApplication::processEvents()(最佳的平衡:一边发送消息,一边睡眠)
sleep()//秒
msleep()//毫秒
usleep()//微秒
以前为了模拟鼠标点击用过这些函数,可以让进程中断,今天发现我原来的做法其实不对.
这组函数会将你当前的线程/进程变为“睡眠”状态。 这个“睡眠”是深度意义的睡眠, 睡眠期间内核不会分配给程序时间片, 所以程序什么都不做, 更不用提界面的刷新了。 直接导致的问题就是用户无法与程序交互。 所以说直接使用sleep函数睡眠是常见的错误方案之一。
另外一种更常见的错误方法是使用QTimer+死循环。 类似下面的代码:
QTimer t;
t.start();
while(t.elapsed() < );
这个简单粗暴的解决方案也是行不通的。 从代码中我们可以发现在while循环中不停的调用elapsed()函数, 等于在这段时间内CPU完全没有机会做别的什么事情。 特别是在Linux这样非抢占式的操作系统中, 这样的死循环造成的影响是致命的, CPU被完全占用, 内核都没有机会调度进程, 别的程序拿不到时间片执行, 系统基本上就是瘫痪状态了。 无论如何, 这种结果都不是我们想要的。(当然拉, 除非你想写的是病毒程序。) 对于我们的程序本身, 虽然它占用了所有的CPU, 但由于它陷入该循环, 程序没有机会进入到GUI事件循环, 导致同样界面是无法刷新的。
其实把上面的代码稍加改变就能得到一个很好的解决方案。 第一步, 解决界面无法刷新的问题。 调用QCoreApplication::processEvents(), 代码如下:
QTimer t;
t.start();
while(t.elapsed() < )
{
QCoreApplication::processEvents();
}
第二步, 解决程序CPU占用率过高的问题 -- 让程序适当睡眠。
QTimer t;
t.start();
while(t.elapsed() < )
{
QCoreApplication::processEvents();
usleep();//sleep和usleep都已经obsolete,Linux下也可以使用nanosleep代替
}
以后要用,就可以直接用上面的代码了,用usleep()就可以了,那个nanosleep()则是Linux中的系统调用,它是使用定时器来实现的,该调用使调用进程睡眠,并往定时器队列上加入一个timer_list型定时器,time_list结构里包括唤醒时间以及唤醒后执行的函数,通过nanosleep()加入的定时器的执行函数仅仅完成唤醒当前进程的功能。系统通过一定的机制定时检查这些队列(比如通过系统调用陷入核心后,从核心返回用户态前,要检查当前进程的时间片是否已经耗尽,如果是则调用 schedule()函数重新调度,该函数中就会检查定时器队列,另外慢中断返回前也会做此检查),如果定时时间已超过,则执行定时器指定的函数唤醒调用进程。当然,由于系统时间片可能丢失,所以nanosleep()精度也不是很高。
Qt Sleep、QCoreApplication::processEvents()(最佳的平衡:一边发送消息,一边睡眠)的更多相关文章
- Qt学习之系列[9] – QCoreApplication:processEvents()可能会引起递归,导致栈溢出崩溃
api含义:QCoreApplication::processEvents() 将处理所有事件队列中的事件并返回给调用者. 问题描述: 当主线程在某个槽函数里正在执行processEvents时, 刚 ...
- QT Sleep(最佳的平衡:一边发送消息,一边睡眠)
转自:http://xiangjie88.iteye.com/blog/898417 sleep()//秒msleep()//毫秒usleep()//微秒以前为了模拟鼠标点击用过这些函数,可以让进程中 ...
- QCoreApplication::processEvents();的作用与TApplication::ProcessMessages的作用完全相同,但是没想到这种用法还有缺点
手动事件处理 最基本的解决方案是明确要求Qt在计算的某些时刻处理等待事件.要做到这一点,必须定期调用QCoreApplication::processEvents(). 下面的例子显示如何做到这一点: ...
- Qt:QCoreApplication
0.说明 QCoreApplication提供了有关当前运行程序的相关信息,当前程序应当是非GUI程序.对于GUI程序,应该用QGuiApplication,而对于采用了Qt Widget模块的程序, ...
- QT的动态翻译功能,可能依赖于消息(事件)机制
QTranslator translator; bool b = translator.load(QString(":/qm/lang_en"));以后,无论使用QObject的t ...
- Qt事件系统之五:事件过滤器和事件的发送
Qt提供了事件过滤器来实现在一个部件中监控其他多个部件的事件.事件过滤器与其他部件不同,它不是一个类,只是由两个函数组成的一种操作,用来完成一个部件对其他部件的事件的监视.这两个函数分别是 insta ...
- Qt通过极光推送向app推送消息
简介 最近在做个项目,当客服端收到防盗的消息通知时向手机app推送一个消息,告知有防盗报警.这么小的功能没必要自己写个推送端,极光推送免费而且推送的成功率高,已经能满足我们的需求了. 极光推送的文档大 ...
- QT串口助手(四):数据发送
作者:zzssdd2 E-mail:zzssdd2@foxmail.com 一.前言 开发环境:Qt5.12.10 + MinGW 实现的功能 串口数据的发送 ascii字符与hex字符的相互转换 自 ...
- qt 向窗口发送消息,键盘输入事件
#include <windows.h> #include <QtDebug> #include <locale> #include <tchar.h> ...
随机推荐
- HDU 2795 Billboard 线段树活用
题目大意:在h*w 高乘宽这样大小的 board上要贴广告,每个广告的高均为1,wi值就是数据另给,每组数组给了一个board和多个广告,要你求出,每个广告应该贴在board的哪一行,如果实在贴不上, ...
- 2020/1/27代码审计学习之SQL注入漏洞
PHP代码审计SQL注入漏洞 0x00 首先明确什么是SQL注入,SQL语句必须掌握. 常见的注入总的来说可以分为两大类:数字型和字符型. 这两类中包含了诸如报错注入,宽字节注入,盲注,二次注入,co ...
- C语言-数组的深入学习
深入学习一下数组1.从内存角度来讲:数组变量就是一次分配多个变量,而且这些变量的地址是连续的,也就是存放这些变量的存储单元是依次相连接的.而且这多个变量必须单独访问,不可以一起访问的.因为他们的地址彼 ...
- bzoj4311向量(线段树分治+斜率优化)
第二道线段树分治. 首先设当前向量是(x,y),剩余有两个不同的向量(u1,v1)(u2,v2),假设u1>u2,则移项可得,若(u1,v1)优于(u2,v2),则-x/y>(v1-v2) ...
- idhttp文件的上传和下载
unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms ...
- zabbix自定义邮件报警
1.启动动作 2.设定发件人邮箱 进入QQ邮箱: 通过短信验证开启如下服务,并生成授权码: 3.配置收件人
- c语言中用简单方法对多维数组进行初始化
例:int array[4][3] = {1,2,3,4,5,6,7,8,9,10,11,12}; 说明:a.由4*3可知,本二维数组包含12个元素,因此初始化时array[0][0] = 1 ,ar ...
- html页面监听事件
今天有个需求,类似以下: <div id="a"> <input name="yinzhangfenlei" id="yinzhan ...
- Django框架的安装与使用
Django框架的安装与使用 在使用Django框架开发web应用程序时,开发阶段同样依赖wsgiref模块来实现Server的功能,我们使用Django框架是为了快速地开发application, ...
- zabbix3.4--监控TCP十一种状态
1.客户端自定义key[root@web01 /etc/zabbix/zabbix_agentd.d]#vim iotps.conf UserParameter=TCP_STATUS_ESTABLIS ...