QThread实现多线程方式

1、QThread类介绍

The QThread class provides a platform-independent way to manage threads.

Thread类提供了与平台无关的方式来管理线程。

A QThread object manages one thread of control within the program. QThreads begin executing in run(). By default, run() starts the event loop by calling exec() and runs a Qt event loop inside the thread.

一个QThread对象管理一个控制线程。该控制线程执行入口是run()函数。

缺省情况下,run()函数内部只是仅仅调用exec()函数,来开启一个事件循环。当然,我们也可以重写run()函数,来实现高级的线程功能。当run()函数结束时,该控制线程也就结束了。

2、使用QObject::moveToThread来实现多线程

controller.h

#ifndef CONTROLLER_H
#define CONTROLLER_H

#include <QObject>
#include <QThread>

class Worker : public QObject
{
    Q_OBJECT
public slots:
    void doWork();
};

class Controller : public QObject
{
    Q_OBJECT
    QThread workerThread;
public:
    explicit Controller(QObject *parent = 0);
    ~Controller();

signals:
    void operate();
public slots:

};

#endif // CONTROLLER_H

controller.cpp

#include "controller.h"
#include <QThread>
#include <QDebug>
 #include <unistd.h>

void Worker::doWork()
{
    //模拟干活
    while(1)
    {
        qDebug() << "doWork in thread " << thread()->currentThreadId();
        sleep(1);
    }
}

Controller::Controller(QObject *parent) : QObject(parent)
{
    Worker *worker = new Worker;
    worker->moveToThread(&workerThread);//worker的槽函数将在workerThread线程执行
    connect(this, SIGNAL(operate()), worker, SLOT(doWork()));
    connect(&workerThread, SIGNAL(finished()), worker, SLOT(deleteLater()));
    workerThread.start();

    emit operate();
}

Controller::~Controller()
{
    workerThread.quit();//终止事件循环,则线程退出
    workerThread.wait();
}

main.cpp

#include "controller.h"
#include <QCoreApplication>

int main(int argc, char *argv[])
{
    QCoreApplication app(argc,argv);

    Controller c1;

    return app.exec();
}

3、通过继承QThread类,并重写run函数,来实现多线程

controller.h

#ifndef _CONTROLLER
#define _CONTROLLER

#include <QThread>

class WorkerThread : public QThread
{
    Q_OBJECT
public:
    WorkerThread(bool &bExited,QObject *parent=0);
    ~WorkerThread();
    void run();
private:
    const bool &m_bExited;
};

class Controller : public QObject
{
    Q_OBJECT
public:
    Controller(QObject *parent=0);
    void startWorkInAThread();
    void stopWork();
private:
    bool m_bExited;
    WorkerThread *m_thread;
};

#endif

controller.cpp

#include "controller.h"
#include <unistd.h>
#include <QDebug>

WorkerThread::WorkerThread(bool &bExited,QObject *parent)
    :m_bExited(bExited),QThread(parent)
{
}

WorkerThread::~WorkerThread()
{
   qDebug() << "WorkerThread::~WorkerThread() was called";
}

//run函数结束,则线程退出
void WorkerThread::run()
{
    while(!m_bExited)
    {
        sleep(1);
        qDebug() << "in WorkerThread::run(), thread = " << currentThreadId();
    }
}

Controller::Controller(QObject *parent):QObject(parent)
{
    m_bExited=false;
}

void Controller::startWorkInAThread()
{
    m_thread=new WorkerThread(m_bExited);
    connect(m_thread,SIGNAL(finished()),m_thread,SLOT(deleteLater()));
    m_thread->start();
}

void Controller::stopWork()
{
    m_bExited=true;
    m_thread->wait();
}

main.cpp

#include "controller.h"
#include <QCoreApplication>
#include <unistd.h>

int main(int argc,char *argv[])
{
    QCoreApplication app(argc,argv);

    Controller c;
    c.startWorkInAThread();
    
    //模拟其他工作
    sleep(5);

    c.stopWork();

    return app.exec();
}

4、对于子类化QThread,需要注意的点

It is important to remember that a QThread instance lives in the old thread that instantiated it, not in the new thread that calls run(). This means that all of QThread's queued slots will execute in the old thread. Thus, a developer who wishes to invoke slots in the new thread must use the worker-object approach; new slots should not be implemented directly into a subclassed QThread.

When subclassing QThread, keep in mind that the constructor executes in the old thread while run() executes in the new thread. If a member variable is accessed from both functions, then the variable is accessed from two different threads. Check that it is safe to do so.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

历史五千年

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值