头图

需要注意的是,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();
}

Daydaydaydaydream
1 声望0 粉丝

引用和评论

0 条评论