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