Qt: 如何实现 "per minute"定时器?避免失火和双火的更好选择?

标签 qt events optimization timer synchronization

我在Windows7平台上使用Qt5。
在我当前的应用程序中,我需要一个计时器,从 00 分钟到 59 分钟每分钟(“每分钟”)触发...
我尝试了各种想法,但我的(以前的)解决方案存在一些问题,例如:失火(某一分钟没有触发超时)或双火(同一分钟触发两次超时!)。
最后,我目前达到了这个实现:

static QTimer timer;

static int GetInterval()
{
    QDateTime now(QDateTime::currentDateTime());
    return ((60 - now.time().second()) * 1000 - now.time().msec());
}

void TEST_TIMER(void)
{
    QObject::connect(&timer, &QTimer::timeout, []()
    {
    qDebug() << " Triggered! " << QDateTime::currentDateTime().time().minute()
                               << QDateTime::currentDateTime().time().second()
                               << QDateTime::currentDateTime().time().msec();
        timer.start(GetInterval());
    } );
    timer.start(GetInterval());
}    

这是输出:

 Triggered!  34 59 550
 Triggered!  35 0 3
 Triggered!  36 0 15
 Triggered!  37 0 28
 Triggered!  38 0 41
 Triggered!  39 0 54
 Triggered!  40 0 68
 Triggered!  41 0 82
 Triggered!  42 0 97
 Triggered!  43 0 109
 Triggered!  44 0 123
 Triggered!  45 0 137
 Triggered!  46 0 149
 Triggered!  47 0 165
 Triggered!  48 0 178
 Triggered!  49 0 192
 Triggered!  50 0 205
 Triggered!  51 0 217
 Triggered!  52 0 231
 Triggered!  53 0 244
     ...   

看起来不错,除了第一行: 已触发! 34 59 550 :( 为什么?
另外,为什么会有大约 12-13 毫秒/分钟的上升速度?
所以,我不是这方面的专家,我更愿意问:
这个实现可以吗?是否可以改进以避免出现双发和/或失火等不愉快的情况?

最佳答案

来自 QTimer description (Qt::CoarseTimer 是默认设置):

For Qt::CoarseTimer and Qt::VeryCoarseTimer types, QTimer may wake up earlier than expected, within the margins for those types: 5% of the interval for Qt::CoarseTimer and 500 ms for Qt::VeryCoarseTimer.

因此,如果准确率为 5%,您的第一枪可能会比预期早得多,这解释了:

Triggered!  34 59 550
Triggered!  35 0 3

如果计时器(恰好)在 0 分钟之前计时,它会再次计时以对齐尚未到达的分钟,即使它还有几毫秒。

如果您使用 Qt::PreciseTimer 代替,它永远不会比预期更早超时,因此您不会遇到这个问题(确保用几毫秒填充延迟)。

Qt::CoarseTimer 也可能解释了您看到的小漂移,因为没有任何内容表明误差幅度是随机的。

关于Qt: 如何实现 "per minute"定时器?避免失火和双火的更好选择?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34872552/

相关文章:

c++ - 使用 CGAL 简化组合映射

performance - 测量 Qt 应用程序性能

linux - 如何在 Qt 中停用窗口

java - Java 中自己的事件无法修改类对象?

c++ - 缓存 std::vector 的大小是否更快

php - 如何避免每次循环运行时都进行查询? (优化代码)

c++ - 使用 QOpenGLTexture 和 QOpenGLFrameBufferObject 的多重纹理

javascript - 使用 onclick 调用函数或使用 .click 绑定(bind)事件哪个更好?

java - 在swing中拖动对象,MouseMotionListener是在对象中还是在JPanel中?

iphone - 计算最佳运输容器空间分配