Qt基础开发之Qt多线程类QThread与Qt定时器类QTimer的详细方法与实例

2020-03-16 12:01:40王旭

Qt多线程

我们之前的程序都是单线程运行,接下来我们开始引入多线程。就相当于以前的一个人在工作,现在多个人一起工作。

Qt中非常有必要使用多线程,这是因为,Qt应用是事件驱动型的,一旦某个事件处理函数处理时间过久,就会造成其它的事件得不到及时处理。

Qt中使用QThread来管理线程,一个QThread对象,就是一个线程。QThread对象也有消息循序exec()函数,用来处理自己这个线程的事件。

Qt实现多线程有两种方式

​1、Qt第一种创建线程方式

首先要继承QThread

重写虚函数QThread::run

[virtual protected] void QThread::run()
 /*
 * 基类QThread的run函数只是简单启动exec()消息循环
 */

例如:

#include <QApplication>
#include <QThread>
#include <QDebug>
class MyThread : public QThread
{
public:
 void run()
 {
  qDebug() << "QThread begin" << endl;
  qDebug() << "child thread" << QThread::currentThreadId() << endl;
  QThread::sleep(5);
  qDebug() << "QThread end" << endl;
  exec();
 }
};
​
int main(int argc, char** argv)
{
 QApplication app(argc, argv);
​
 MyThread thread;
 thread.start();
 qDebug() << "main thread" << QThread::currentThreadId() << endl;
 QThread::sleep(5);
 qDebug() << "main thread" << QThread::currentThreadId() << endl;
 thread.quit();
 qDebug() << "main thread thread.quit()" << endl;
 tread.wait();
 qDebug() << "main thread thread.wait()" << endl;
 return app.exec();
}

使用QThread的quit可以退出线程的消息循环,有时候不是马上退出,需要等到cpu的控制权交还给线程的exec()。

一般在子线程退出的时候需要主线程去回收资源,可以调用QThread的wait,等待子线程的退出,然后回收资源.

2、Qt第二种创建线程方式

继承 QObject

实例化一个QThread对象

实现槽函数.

QObject子类对象通过moveToThread将自己放到线程QThread对象中.

调用QThread对象的start函数启动线程

必须通过发射信号来让槽函数在线程中执行,发射的信号存放在线程exec()消息队列中。

例如:

mywork.h

#ifndef MYWORK_H
#define MYWORK_H
#include <QThread>
#include <QDebug>
class MyWork : public QObject
{
 Q_OBJECT
public slots:
 void workSlot()
 {
  qDebug() << "QThread begin" << endl;
  qDebug() << "child thread" << QThread::currentThreadId() << endl;
  QThread::sleep(5);
  qDebug() << "QThread end" << endl;
 }
};
#endif // MYWORK_H

widget.cpp

#include <QApplication>
#include <QThread>
#include <QDebug>
#include "mywork.h"
​
int main(int argc, char** argv)
{
 qDebug() << "main thread" << QThread::currentThreadId() << endl;
 QApplication app(argc, argv);
 QThread thread;
 MyWork work;
 work.moveToThread(&thread);
 QObject::connect(&thread, SIGNAL(started()), &work, SLOT(workSlot()));
 thread.start();
 
 QThread::sleep(6);
 qDebug() << "thread is runing" << thread.isRunning() << endl;
 thread.quit(); //调用quit让线程退出消息循环,否则线程一直在exec循环中
 thread.wait(); //调用完quit后紧接着要调用wait来回收线程资源
 qDebug() << "thread is runing" << thread.isRunning() << endl;
​
 return app.exec();
}