zoukankan      html  css  js  c++  java
  • QT Sleep(最佳的平衡:一边发送消息,一边睡眠)

    转自:http://xiangjie88.iteye.com/blog/898417

    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()精度也不是很高。

    http://blog.csdn.net/emdfans/article/details/42214621

  • 相关阅读:
    【WPF】ListBox GridViewColumn Header 文字换行、文字多行显示
    【Unity】讯飞语音识别SDK
    【Unity】UGUI无法修改UI元素的Pivot锚点位置
    【Unity】EasyTouch5触屏检测
    【Unity】序列化字典Dictionary的问题
    【WPF】自定义形状的按钮Button
    【WPF】图片按钮的单击与双击事件
    【Unity】ShareSDK、SMSSDK的基本使用与常见问题
    【Unity】不能新建项目
    【Java】移动JDK路径后,修改环境变量不生效 Error: could not open `C:Program FilesJavajre1.8.0_131libamd64jvm.cfg'
  • 原文地址:https://www.cnblogs.com/findumars/p/5599434.html
Copyright © 2011-2022 走看看