前言
程序实现多线程的作用这里就不赘述了,这里主要介绍QT多线程。QT使用多线程非常方便,用QThread类能非常方便地操作线程,配合QT特色的信号和槽机制(signal-slot)和QMutex类锁即可完成各种跨线程的操作。
使用QThread
首先需要包含头文件QThread:
#include <QThread>
新建一个QThread与新建一个变量类似:
QThread myThread;
那么如何把需要运行程序放入新建的线程呢?我们可以新建一个名为MyObject的类:
#include <QObject>
#include <QDebug>
#include <iostream>
class MyObject : public QObject {
Q_OBJECT
public:
MyObject() {};
~MyObject() {}
public slots:
void show() {
qDebug() << "hello";
}
};
接着在mainwindow.cpp的MainWindow构建函数中调用:
QThread * myThread = new QThread;
my = new MyObject;
my->moveToThread(myThread);
myThread->start();
connect(myThread, SIGNAL(started()), my, SLOT(first()));
这样my这个MyObject类的槽函数show()就会在新建的myThread线程中运行。
然而,以下还有一种更实用的方法,由于比较长,直接上源码,后面会解释:
thread.h
#ifndef THREAD_H
#define THREAD_H
#include <QThread>
#include <iostream>
#include <QDebug>
class Thread : public QThread
{
Q_OBJECT
public:
Thread();
void stop();
protected:
void run();
void printMessage();
private:
QString messageStr;
volatile bool stopped;
};
#endif // THREAD_H
thread.cpp
#include "thread.h"
Thread::Thread()
{
stopped = false;
}
void Thread::run()
{
while(!stopped)
{
printMessage();
}
stopped = false;
}
void Thread::stop()
{
stopped = true;
}
void Thread::printMessage()
{
qDebug()<< "hello";
usleep(5);
}
以上的代码新建了一个Thread类,并且重载了run()函数,需要在新线程中运行的代码放在run()中。使用时,在mainwindow类中定义一个Thread成员,接着在需要的地方调用start()即可:
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QThread>
#include <iostream>
#include <QDebug>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private:
Ui::MainWindow *ui;
Thread myThread;
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
myThraed.start();
}
MainWindow::~MainWindow()
{
delete ui;
}
这样就会不断输出hello.
一些QThread使用要点
- 新建的QThread变量可以理解为管理我们新建的线程的类,它本身仍然在原线程里,run()函数里的内容才是新线程。
- 基于第一点,我们自己定义的Thread类中如果有槽函数,这个槽函数将在原线程而非新线程中运行,请务必注意!
- QThread的安全销毁需要在mainwindow.cpp包含头文件:
#include <QCloseEvent>
并且在mainwindow.cpp中重载:
protected:
void closeEvent(QCloseEvent *event);//重载,防止线程驻留在系统
他的函数定义为:
void MainWindow::closeEvent(QCloseEvent *event)
{
Thread.stop();
Thread.wait();
event->accept();
}