博客 / 詳情

返回

QThread 使用方法

需要注意的是,Qt 的 GUI 相關的實現以及更新只能在主線程中完成。

簡易線程創建並使用

auto tempHandleDicomInfoThread = new QThread();
connect(tempHandleDicomInfoThread, &QThread::started, [=]() {
    qDebug() << "tempHandleDicomInfoThread started" << tempHandleDicomInfoThread->currentThreadId();
    foo();//do something
    tempHandleDicomInfoThread->quit();
});

connect(tempHandleDicomInfoThread, &QThread::finished, [=]() {
    qDebug() << "tempHandleDicomInfoThread finished" << tempHandleDicomInfoThread->currentThreadId();
    tempHandleDicomInfoThread->deleteLater();
});

tempHandleDicomInfoThread->start();

這裏可以體現出創建一個線程公有的步驟:

  1. 創建一個 QThread 線程對象
  2. start 這個線程
  3. 在運行完成後 quit
  4. 並在線程發出 finished 信號後 delete 這個線程

繼承 QThread 實現多線程

許多博客中寫明瞭並不推薦該用法而是推薦下面的 moveToThread 實現方法,具體原因還在瞭解中。

class MyThread : public QThread
{
    Q_OBJECT
public:
    MyThread(QObject* parent = nullptr);
signals:                
    void signal_mThread();//自定義發送的信號
public slots:                
    void slotMyThread();//自定義槽
protected:
    void run() override;
};
#include <mythread.h>
Controller::Controller(QObject *parent) : QObject(parent)
{
    myThrd = new MyThread;
    connect(myThrd, &MyThread::signal_mThread, this,   &Controller::handleResults);
    connect(myThrd, &QThread::finished,        this,   &QObject::deleteLater);            //該線程結束時銷燬
    connect(this,   &Controller::operate,      myThrd, &MyThread::myThreadSlot);
 
    myThrd->start();
    emit operate();
}
 
Controller::~Controller()
{
    myThrd->quit();
    myThrd->wait();
}

這裏我們創建了一個基於 QThread 的類,來實現數據的處理。通過接口 operate() 向其傳入數據,通過 signal_mThread() 傳出處理完成的數據。

moveToThread

//moveToThread
class Worker : public QObject {
    Q_OBJECT
public:
    Worker();
    ~Worker();
 
public slots:
    void process(){
        qDebug()<<"hello world";
        emit finfished();
    }
 
signals:
    void finished();
    void error(QString err);
 
private:
    // add your variables here
};
QThread* thread = new QThread;
Worker* worker = new Worker();
worker->moveToThread(thread);
connect(worker, SIGNAL(error(QString)), this, SLOT(errorString(QString)));
connect(thread, SIGNAL(started()), worker, SLOT(process()));
connect(worker, SIGNAL(finished()), thread, SLOT(quit()));
connect(worker, SIGNAL(finished()), worker, SLOT(deleteLater()));
connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
thread->start();

QThread 的使用應該與常規線程實例非常相似:

  1. 準備一個對象 QObject 類,其中包含所有所需的功能
  2. 創建一個新的 QThread 實例,使用 QObject 實例的 moveToThread(QThread*) 將 QObject 推送到該實例上
  3. 並在 QThread 實例上調用 start()

線程同步

//互斥鎖 QMutex
class Worker : public QObject {
    Q_OBJECT
public:
    Worker();
    ~Worker();

    void setMutex(QMutex &mutex){mMutex = mutex};
 
public slots:
    void process(){
        mMutex->lock();
        qDebug()<<"hello world";
        emit finfished();
        mMutex->unlock();
    }
 
signals:
    void finished();
    void error(QString err);
 
private:
    QPointer<QMutex> mMutex;
};
void foo(){
    QMutex mutex;
    QThread* thread = new QThread;
    
    auto worker1 = new worker();
    auto worker2 = new worker();
    
    //connect ......

    worker1->setMutex(mutex);
    worker2->setMutex(mutex);

    worker1->start();
    worker2->start();
}
user avatar
0 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.