項目需要,又開始搞qt的多線程編程。
QThread類並不是代表一個新的線程,而是QT提供的一個介面,用於控制一個子線程。每個QThread的執行個體就代表著對一個新線程的一個控制類。所以重寫run函數,在我看來是很不恰當的,我講的都是繼承QObject類再使用moveToThread函數。
使用多線程就是希望有些工作能夠分配給其他的線程來做,這是我們最關心的。
下面是我講解的一個小小的例子,看一下多線程是怎麼工作的。
直接上代碼
#ifndef TESTOBJ_H#define TESTOBJ_H#include <QObject>#include <QDebug>#include <QThread>class TestObj : public QObject{ Q_OBJECTpublic: explicit TestObj(QObject *parent = 0); ~TestObj(){qDebug() << "obj ~" << '\n' << QThread::currentThreadId(); }signals: public slots: void slt_printInfo() { qDebug() << QThread::currentThreadId(); } };#endif // TESTOBJ_H#include "testobj.h"TestObj::TestObj(QObject *parent) : QObject(parent){}#ifndef THREADMANAGE_H#define THREADMANAGE_H#include <QThread>class ThreadManage{public: ThreadManage(QThread *p_thread); ~ThreadManage(); QThread* value() const { return p_h; }private: QThread *p_h;};#endif // THREADMANAGE_H#include "threadmanage.h"#include <QDebug>ThreadManage::ThreadManage(QThread *p_thread): p_h(p_thread){}ThreadManage::~ThreadManage(){ p_h->quit(); p_h->wait(); p_h->deleteLater(); qDebug() << "Thread ~~";}#include <QApplication>#include <QPushButton>#include "testobj.h"#include "threadmanage.h"int main(int argc, char* argv[]){ QApplication app(argc,argv); ThreadManage tm(new QThread()); ThreadManage tm2(new QThread()); TestObj *to = new TestObj; TestObj to2; to->moveToThread(tm.value()); to2.moveToThread(tm2.value()); tm.value()->start(); tm2.value()->start(); QPushButton button(QObject::tr("退出")); QObject::connect(&button,SIGNAL(clicked()),to,SLOT(slt_printInfo())); button.show(); qDebug() << QThread::currentThreadId(); return app.exec();}
ThreadManage是我自己封裝的簡單的資源管理的類,TestObj繼承QObject其中在解構函式和一個槽函數中輸入線程的ID。看一下啟動並執行結果
3055118144 是在主函數中的顯示
2978155328 是那個槽函數
obj ~
3055118144 是一個解構函式,
從中我們可以看出,繼承自QObject的類槽函數在新線程中運行,而實體建立和析構時還是在主線程中。