zoukankan      html  css  js  c++  java
  • Qt 延时

    第一部分:

    关于sleep函数,我们先来看一下他的作用:sleep函数是使调用sleep函数的线程休眠,线程主动放弃时间片。当经过指定的时间间隔后,再启动线程,继续执行代码。sleep函数并不能起到定时的作用,主要作用是延时。在一些多线程中可能会看到sleep(0);其主要目的是让出时间片。sleep函数的精度非常低,当系统越繁忙的时候它精度也就越低,有时候我们休眠1秒,可能3秒后才能继续执行。它的精度取决于线程自身优先级、其他线程的优先级,以及线程的数量等因素,所以说sleep函数是不能用来精确计时的。 Qt为我们提供了几个可以用于线程Sleep的函数,分别是: void QThread::sleep ( unsigned long secs )   [static protected] void QThread::msleep ( unsigned long msecs )   [static protected] void QThread::usleep ( unsigned long usecs )   [static protected] sleep的单位分别是秒、毫秒、微秒。 但是现在问题出来了,请仔细看上面的函数定义,函数的访问权限都是protected,这就意味着,我们必须在QThread或者他的继承类中使用这三个函数。 但是我们可能需要在非继承QThread的类中来使用sleep函数。那这该这么办呢?下面我就给大家提供几种解决方法。 1.    processEvents     QTime dieTime = QTime::currentTime().addMSecs(svalue);     while( QTime::currentTime() < dieTime )     QCoreApplication::processEvents(QEventLoop::AllEvents, 100); 调用processEvents会让Qt继续处理线程所在的消息队列中未处理的消息,直到消息队列中没有消息可以处理。当进行长时间的操作的时候可以调用此函数(比方说拷贝文件)。这个函数可能和我们要使用msleep的本意有差别,但是使用它可以在svalue时间内处理events,从而达到类似sleep的目的。 2.        QWaitCondition        QWaitCondition wait;        wait.wait(time); wait的单位是milliseconds,但是wait和sleep的作用是不同的。 sleep()方法是使线程停止一段时间的方法。在sleep 时间间隔期满后,线程不一定立即恢复执行。这是因为在那个时刻,其它线程可能正在运行而且没有被调度为放弃执行,除非 (a)“醒来”的线程具有更高的优先级。 (b)正在运行的线程因为其它原因而阻塞。 wait()会使调用它的线程暂停执行,被调对象进入等待状态,直到被唤醒或等待时间到。 3.        查看sleep的源代码,使用Qt在win下和*nix下的sleep函数。 Windows下的sleep的代码为: void QThread::sleep(unsigned long secs) {     ::Sleep(secs * 1000); } sleep的单位为秒。 *nix下sleep的代码为: void QThread::sleep(unsigned long secs) {     struct timeval tv;     gettimeofday(&tv, 0);     struct timespec ti;     ti.tv_sec = tv.tv_sec + secs;     ti.tv_nsec = (tv.tv_usec * 1000);     thread_sleep(&ti); } static void thread_sleep(struct timespec *ti) {     pthread_mutex_t mtx;     pthread_cond_t cnd;     pthread_mutex_init(&mtx, 0);     pthread_cond_init(&cnd, 0);     pthread_mutex_lock(&mtx);     (void) pthread_cond_timedwait(&cnd, &mtx, ti);     pthread_mutex_unlock(&mtx);     pthread_cond_destroy(&cnd);     pthread_mutex_destroy(&mtx); } 我们可以对这两个函数进行简单的封装,从而达到真正的sleep的作用。 版权声明
    本文为原创作品,请尊重作者的劳动成果。转载必须保持文章完整性,并以超链接形式注明原始作者“tingsking18”和主站点地址,方便其他朋友提问和指正。http://jinsuo2007.blog.163.com/blog/static/192279952011875724406/



    Qt4——程序延时的方法 http://blog.csdn.net/sunnyskyliu/article/details/6721277
    1: void QTimer::singleShot ( int msec, QObject * receiver, const char* member ) [static] 
    样例: #include<QApplication> #include<QTimer> int main(int argc, char *argv[]) {   QApplication app(argc, argv);   QTimer::singleShot(600000,&app, SLOT(quit()));   ...   return app.exec(); }
    2:以毫秒计
        QTimen=QTime::currentTime();     QTimenow;     do{          qDebug()<<"jjmm";         now=QTime::currentTime();     }   while(n.msecsTo(now)<=1);

    3:以秒计
    QDateTime n2=QDateTime::currentDateTime();   QDateTime now;   do{   now=QDateTime::currentDateTime();   } while(n2.secsTo(now)<=6);//6为需要延时的秒数

    第二部分:

    QT_让程序休息一会 sleep
    2011-09-22 15:48

    在qt中不能直接使用sleep()函数,经查看可以发现,sleep在QThread中定义的有,但他是private模式,外部函数无法调用。利用一下方法可以实现sleep效果。我用的是第一种方法。

    方法一:

    class SleeperThread : public QThread { public:     static void msleep(unsigned long msecs)     {         QThread::msleep(msecs);     } };

    // 调用方法 SleeperThread::msleep(1000);

    方法二:

    QMutex mutex; QWaitCondition sleep; mutex.lock(); sleep.wait(&mutex, 1000); mutex.unlock();

    来自:http://hi.baidu.com/%CE%D2%B6%A5%D0%ED%CE%A1/blog/item/bc0e5fd9d62af0c28c1029c3.html
     
     
     
    第三部分:
    sleep()//秒 msleep()//毫秒 usleep()//微秒 以前为了模拟鼠标点击用过这些函数,可以让进程中断,今天发现我原来的做法其实不对. 这组函数会将你当前的线程/进程变为“睡眠”状态。 这个“睡眠”是深度意义的睡眠, 睡眠期间内核不会分配给程序时间片, 所以程序什么都不做, 更不用提界面的刷新了。 直接导致的问题就是用户无法与程序交互。 所以说直接使用sleep函数睡眠是常见的错误方案之一。 另外一种更常见的错误方法是使用QTimer+死循环。 类似下面的代码: QTimer t; t.start(); while(t.elapsed() < 250);
    这个简单粗暴的解决方案也是行不通的。 从代码中我们可以发现在while循环中不停的调用elapsed()函数, 等于在这段时间内CPU完全没有机会做别的什么事情。 特别是在Linux这样非抢占式的操作系统中, 这样的死循环造成的影响是致命的, CPU被完全占用, 内核都没有机会调度进程, 别的程序拿不到时间片执行, 系统基本上就是瘫痪状态了。 无论如何, 这种结果都不是我们想要的。(当然拉, 除非你想写的是病毒程序。) 对于我们的程序本身, 虽然它占用了所有的CPU, 但由于它陷入该循环, 程序没有机会进入到GUI事件循环, 导致同样界面是无法刷新的。
    其实把上面的代码稍加改变就能得到一个很好的解决方案。 第一步, 解决界面无法刷新的问题。 调用QCoreApplication::processEvents(), 代码如下: QTimer t; t.start(); while(t.elapsed() < 250) { QCoreApplication::processEvents(); }
    第二步, 解决程序CPU占用率过高的问题 -- 让程序适当睡眠。 QTimer t; t.start(); while(t.elapsed() < 250) { QCoreApplication::processEvents(); usleep(10000);//sleep和usleep都已经obsolete,Linux下也可以使用nanosleep代替 }
    以后要用,就可以直接用上面的代码了,用usleep()就可以了,那个nanosleep()则是Linux中的系统调用,它是使用定时器来实现的,该调用使调用进程睡眠,并往定时器队列上加入一个timer_list型定时器,time_list结构里包括唤醒时间以及唤醒后执行的函数,通过nanosleep()加入的定时器的执行函数仅仅完成唤醒当前进程的功能。系统通过一定的机制定时检查这些队列(比如通过系统调用陷入核心后,从核心返回用户态前,要检查当前进程的时间片是否已经耗尽,如果是则调用 schedule()函数重新调度,该函数中就会检查定时器队列,另外慢中断返回前也会做此检查),如果定时时间已超过,则执行定时器指定的函数唤醒调用进程。当然,由于系统时间片可能丢失,所以nanosleep()精度也不是很高。
  • 相关阅读:
    javascript之this的深入学习
    记一次前端面试
    nodejs学习
    Javascript内置对象
    Javascript事件
    全屏滚动插件小结
    Javascript函数的深入学习
    近年来前端开发趋势,MVVM框架,Vue.js的核心思想
    Javascript的for ... in循环
    JavaScript的对象深入学习
  • 原文地址:https://www.cnblogs.com/luxiaolai/p/4259681.html
Copyright © 2011-2022 走看看