Doc*_*sha 1 c++ qt multithreading qtimer
好的,所以我在QTimer中完全迷失了.问题是:我有多线程应用程序,我需要在QTimer的超时上做一些工作.我这样做了:
QTimer* timer = new QTimer();
timer->setSingleShot(true);
connect(timer, SIGNAL(timeout()), someObject, SLOT(work()));
Run Code Online (Sandbox Code Playgroud)
这没用.有时,work()根本没有被调用,有时它在我关闭程序时被调用,有时候看起来都很正常.
所以我开始想到计时器需要线程.提供MCV示例:
class Tester : public QObject
{
Q_OBJECT
public:
Tester(QObject* par = 0) : QObject(par)
{
}
public slots:
void greet()
{
qDebug()<<"hello";
}
};
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QTimer* timer1 = new QTimer();
QThread* thread = new QThread();
Tester* tester = new Tester();
timer1->setInterval(500);
timer1->setSingleShot(false);
timer1->moveToThread(thread);
QObject::connect(thread, SIGNAL(started()), timer1, SLOT(start()));
QObject::connect(timer1, SIGNAL(timeout()), tester, SLOT(greet()));
QObject::connect(timer1, SIGNAL(timeout()), timer1, SLOT(deleteLater()));
QObject::connect(timer1, SIGNAL(destroyed()), thread, SLOT(quit()));
thread->start();
thread->wait();
delete thread;
delete tester;
return a.exec();
}
Run Code Online (Sandbox Code Playgroud)
这个例子什么也没做.它没有问候我,所以不调用超时,它不会结束,所以线程不会停止.所以问题是:
1.这段代码有什么问题?
2.在多线程环境中如何正确使用QTimer?
只是调用QTimer :: setInterval不会启动QTimer.它只设置发出QTimer :: timeout信号的时间间隔.你没有启动QTimer.使用QTimer :: start.
我想你在这里犯了几个错误.在完成所有连接后,您需要将计时器移动到线程.不确定在线程启动时启动计时器的安全性是多少,因为在那时,计时器将在一个线程中,而线程对象将在另一个线程中.QTimer必须从创建它的同一个线程启动.该QThread对象只是一个线程处理程序,它存在于创建的线程中.请参阅我对您的示例所做的修改:
#include <QCoreApplication>
#include <QThread>
#include <QDebug>
#include <QTimer>
#include <QObject>
//#include "tester.h"
class Tester : public QObject
{
Q_OBJECT
public:
Tester(QObject* par = 0) : QObject(par)
{
}
public slots:
void greet()
{
qDebug()<<"hello";
}
};
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QTimer* timer1 = new QTimer();
QThread* thread = new QThread();
Tester* tester = new Tester();
timer1->setInterval(500);
timer1->setSingleShot(false);
timer1->start();
QObject::connect(timer1, SIGNAL(timeout()), tester, SLOT(greet()));
timer1->moveToThread(thread);
thread->start();
return a.exec();
}
Run Code Online (Sandbox Code Playgroud)
这不是最安全/最好的修复(内存泄漏和其他),但我希望,它是一个可以构建的示例.
这在我看来是正确的,没有内存泄漏的方式QTimer在另一个中使用a QThread:
handler.h中
#ifndef HANDLER_H
#define HANDLER_H
#include <QObject>
class QTimer;
class QThread;
class Tester;
class Handler : public QObject
{
Q_OBJECT
public:
explicit Handler(QObject *parent = 0);
~Handler();
void exec();
private:
QTimer* timer;
QThread* thread;
Tester* tester;
};
#endif // HANDLER_H
Run Code Online (Sandbox Code Playgroud)
handler.cpp
#include "handler.h"
#include "tester.h"
#include <QThread>
#include <QDebug>
#include <QTimer>
#include <QObject>
#include <QCoreApplication>
Handler::Handler(QObject *parent) :
QObject(parent)
{
timer = new QTimer;
thread = new QThread(this);
tester = new Tester(this);
timer->setInterval(500);
timer->setSingleShot(false);
QObject::connect(timer, SIGNAL(timeout()), tester, SLOT(greet()));
QObject::connect(thread, SIGNAL(destroyed()), timer, SLOT(deleteLater()));
}
Handler::~Handler()
{
thread->wait();
}
void Handler::exec()
{
timer->start();
timer->moveToThread(thread);
thread->start();
}
Run Code Online (Sandbox Code Playgroud)
tester.h
#ifndef TESTER_H
#define TESTER_H
#include <QObject>
class Tester : public QObject
{
Q_OBJECT
public:
Tester(QObject* par = 0);
public slots:
void greet();
};
#endif // TESTER_H
Run Code Online (Sandbox Code Playgroud)
tester.cpp
#include "tester.h"
#include <QDebug>
Tester::Tester(QObject *parent) :
QObject(parent)
{
}
void Tester::greet()
{
qDebug()<<"hello";
}
Run Code Online (Sandbox Code Playgroud)
main.cpp中
#include <QCoreApplication>
#include "handler.h"
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
Handler handler;
handler.exec();
return a.exec();
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2333 次 |
| 最近记录: |