最准确的计时器Qt C ++

时间:2018-08-20 09:22:38

标签: c++ qt timer mqtt qtimer

我使用QTimer定期向服务器(MQTT客户端)发送“ Ping”数据包。但是计时器不是绝对准确的。工作一段时间后,它会出现一些延迟并且服务器断开连接。 我尝试使用其他Qt :: TimerType,但这无济于事。 我需要最准确的计时器。你有什么想法吗?

谢谢!


EDIT(Frederik解决方案)


我做了这样的事情:

tthread.h

class TThread : public QThread
{
    Q_OBJECT

    void run();

public:
    explicit TThread(QObject *parent = 0);

signals:

private slots:
    void timerOut();
};

tthread.cpp

TThread::TThread(QObject *parent) : QThread(parent)
{

}

void TThread::run()
{
    QTimer timer;
    connect(&timer, SIGNAL(timeout()), this, SLOT(timerOut()), Qt::DirectConnection);
    timer.start(1000);
    timer.moveToThread(this);
    exec();
}

void TThread::timerOut()
{
    QTime time = QTime();
    qDebug() << time.currentTime().toString();
}

main.cpp

TThread thread;
thread.start();
thread.setPriority(QThread::HighPriority);

2 个答案:

答案 0 :(得分:1)

在一个单独的QThread上运行一个QTimer,它不会执行其他任何操作。 如果您在一个已经很繁忙的线程上运行计时器,则超时事件可能不会按时出现或根本没有出现。

进行工人培训,例如“ PingPacketWorker”,实现执行ping操作的插槽。 制作一个QThread。 连接您的QTimer和PingPacketWorker信号/插槽。 启动计时器。 在PingPacketWorker和QTimer上调用moveToThread,由于moveToThread,计时器应重新启动,请注意,您只能在所有者线程上启动/停止它!

由于您要求“最准确的”解决方案,因此您还可以提高QThread的优先级...

更新:

还要设置QTimer :: setTimerType(Qt :: PreciseTimer)

默认的Qt::CoarseTimer精度较低(间隔的5%)

答案 1 :(得分:0)

#pragma once

#include <cstdint>
#include <QObject>

class PrecisePolling : public QObject
{
    Q_OBJECT
private:
    std::uint64_t previousPollingTime;
public:
    PrecisePolling();

public slots:
    void doPolling();

#include "precisepolling.h"
#include "QDateTime"
#include <QDebug>

PrecisePolling::PrecisePolling()
    : previousPollingTime(QDateTime::currentMSecsSinceEpoch())
{}

void PrecisePolling::doPolling()
{
    const std::uint64_t ms = QDateTime::currentMSecsSinceEpoch();
    qDebug() << ms - previousPollingTime;
    previousPollingTime = ms;
}

#include <QCoreApplication>
#include <QThread>
#include <QTimer>
#include "precisepolling.h"

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    QThread thread;
    QTimer timer;
    PrecisePolling pp;

    timer.setInterval(1000);
    timer.setTimerType(Qt::PreciseTimer);

    QObject::connect(&timer, &QTimer::timeout, &pp, &PrecisePolling::doPolling);
    timer.start();
    timer.moveToThread(&thread);
    pp.moveToThread(&thread);

    thread.start(QThread::Priority::TimeCriticalPriority);

    return a.exec();
}