1. 程式人生 > >QT5(16)多執行緒 Thread

QT5(16)多執行緒 Thread

推薦一部落格
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錯誤。)