QT5(16)多執行緒 Thread
阿新 • • 發佈:2019-01-22
推薦一部落格
Qt提供兩種多執行緒方式。一種繼承QThread類;另一種採用movetothread。在Qt中採用事件迴圈(QEvenLoop)處理時間。
一、繼承QThread
Qt執行緒中預設run函式呼叫exec()執行事件迴圈。但是如果繼承的run函式沒有啟動事件迴圈,run函式就不會阻塞。如果我們需要啟動執行緒內的事件迴圈,就需要手動執行exec()。
注意繼承自QThread的類在子執行緒中只有run()函式部分能夠在子執行緒中執行。其他部分還是在主執行緒中執行。
#include <QtCore>
class Thread : public QThread
{
private:
void run()
{
qDebug()<<"From worker thread: "<<currentThreadId();
}
};
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
qDebug()<<"From main thread: "<<QThread::currentThreadId();
Thread t;
QObject::connect(&t , SIGNAL(finished()), &a, SLOT(quit()));
t.start();
return a.exec();
}
如果run函式沒有啟用事件迴圈,那麼一般情況下我們通過設定flag來結束程序。啟用事件迴圈exec()後,執行緒不斷做著迴圈遍歷事件佇列的工作,呼叫QThread的quit()或exit()方法使停止執行緒,儘量不要使用terminate(),會造成資源不能釋放,甚至互斥鎖還處於加鎖狀態。其中quit與terminate是槽,可以直接用訊號連線關閉執行緒。執行緒被終止時,所有等待該執行緒Finished的執行緒都將被喚醒。
#include "QThread"
#include "QMutexLocker"
#include "QMutex"
class Thread:public QThread
{
Q_OBJECT
public:
Thread();
void stop();
private:
bool m_stopFlag;
QMutex mutex;
protected:
void run();
};
Thread::Thread()
{
m_stopFlag = false;
}
void Thread::stop()
{
QMutexLocker locker(&mutex);
m_stopFlag = true;
}
void Thread::run()
{
while(1){
{
QMutexLocker locker(&mutex);
if(m_stopFlag)
break;
}
qDebug()<<"This is in thread["<<currentThreadId()<<"]."<<(int)currentThread();
sleep(2);
}
m_stopFlag = false;
}
二、movetothread
目前的推薦做法:子類繼承QObject,然後使用movetothread將物件交給子執行緒,當訊號發出後,Qt會將SLOT函式提交給子執行緒,放在子執行緒中執行。類的SLOT的函式都能夠線上程中執行。
include <QtCore>
class Worker : public QObject
{
Q_OBJECT
private slots:
void onTimeout()
{
qDebug()<<"Worker::onTimeout get called from?: "<<QThread::currentThreadId();
}
};
#include "main.moc"
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
qDebug()<<"From main thread: "<<QThread::currentThreadId();
QThread t;
QTimer timer;
Worker worker;
QObject::connect(&timer, SIGNAL(timeout()), &worker, SLOT(onTimeout()));
timer.start(1000);
worker.moveToThread(&t);
t.start();
return a.exec();
}
三、connect最後一個引數
引數 | 解釋 |
---|---|
Qt::AutoConnection | 預設連線方式,如果訊號與槽在同一執行緒,等同於直接連線;在不同執行緒,等同於佇列連線。 |
Qt::DirectConnection | 無論槽函式所屬物件在哪個執行緒,槽函式都在訊號的執行緒內執行,使用該連線,槽將會不線上程執行。 |
Qt::QueuedConnection | 槽函式在物件的當前執行緒中按照佇列順序執行。如果執行緒停止,就會等待下一次啟動執行緒時再按佇列順序執行。 |
Qt:: BlockingQueuedConnection | 只有槽函式線上程執行完才會返回,否則傳送執行緒也會等待。 |
Qt::UniqueConnection | 與AutoConnect相同,只是不能重複連線相同的訊號和槽。 |
Qt::AutoCompatConnection | 相容老版本 |
附上練手的百度私鏈破解程式(已失效,目前多次密碼出錯,連結404錯誤。)