QThread线程的运行和退出

关于QT退出线程,一直迷迷糊糊的,凑活着能用就行,出了问题总觉得莫名其妙,现在静下心来总结一下。

感谢

QThread的用法:开启与退出

Qt QThread 这是我 见过解析最全面的一片文章

 

线程运行有两种方式

#include 
#include 
#include 
#include 
#include 

/* Qt的线程可以多次启用 
     
   这是第一种方式,使用 QObject::MoveToThread()
    1.创建你的工作类 Worker,必须继承于 QObject
    2.创建你的执行类 Controller,类内声明 QThread变量thread
    3.在Controller内将 Worker执行 MoveToThread(QThread* thd)
    4.在Controller内connect其他信号到运行函数(我的是work())。运行函数内如果是死循环,则需要自己加退出标志,然后通过其他函数操作这个变量,使死循环退出。
    5.启动 (我的 Controller ::Start() )
    6.需要时停止 (我的 Controller::Stop )
*/

class Worker : public QObject
{
    Q_OBJECT
public:
    explicit Worker(QObject *parent = nullptr)  : QObject(parent) {}
    bool quit = false;
    int index = 0;
    void work()
    {
        index = 0;
        while (!quit) {
            index++;
            qDebug() << "i'm working " << index;
            QThread::msleep(500);
        }
        qDebug() << "worker:" << QThread::currentThread();
        quit = false;
    }
};


class Controller : public QObject
{
    Q_OBJECT
public:
    explicit Controller(QObject *parent = nullptr)  : QObject(parent)
    {
        worker.moveToThread(&thread);
        connect(this, &Controller::sig_Started, &worker, &Worker::work);
    }
    virtual ~Controller() {}

    Worker worker;
    QThread thread;


    void Start()
    {
        //线程函数启动,不能在此直接调用worker.work(),需要有connect连接一下才能将该函数放到线程之内运行
        thread.start();
        emit sig_Started();
    }
    void Stop(){
        qDebug() << "ready to exit";
        worker.quit = true;
        thread.wait();
        qDebug() << "exit done";
    }

signals:
    void sig_Started();
};


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

    qDebug() << "thread is "  << QThread::currentThread();

    Controller ctl;
    ctl.move2thd();
    ctl.Start();


    //10s后退出
    QThread::sleep(10);
    qDebug() << "main call thread quit";
    ctl.Stop();

    //再次启动
    qDebug() << "start again";
    ctl.Start();
    //10s后退出
    QThread::sleep(15);
    qDebug() << "main call thread quit";
    ctl.Stop();


    return a.exec();
}

 

#include 
#include 
#include 
#include 
#include 

/* Qt的线程可以多次启用 
    这是第二种方式 
    1.定义一个继承于 QThread的类,类内实现函数 
        void run() override;  //你的线程执行内容
    2.如果你的不是死循环,可以在 run() 内直接执行,如果是死循环,可以用上面第一种方式的 死循环+退出标志位 的方式写,也可以使用定时器的方式
    3.定时器的方式。在 run() 函数内启动定时器,这个定时器是在当前线程上启动的,而非主线程。 run() 函数的最后一行记得加上  exec(),使线程启动消息循环,这样不用自己再加退出标志变量。此时线程函数已开始执行。
    4.如果需要停止,在其他地方调用 exit() wait(),必须在上一步执行了exec(),线程才能收到 exit()

*/


class Work2 : public QThread
{
    Q_OBJECT
public:
    Work2(QObject* parent = nullptr): QThread(parent){}
    ~Work2() { ptm->deleteLater(); }

    int index = 0;
    void tmot()
    {
        index++;
        qDebug() << "thread is " << QThread::currentThread();
        qDebug() << "i'm working " << index;
    }
    QTimer* ptm = nullptr;
    void run() override
    {
        index = 0;
        ptm = new QTimer();
        bool res = connect(ptm, &QTimer::timeout, this, &Work2::tmot, Qt::DirectConnection);
        ptm->start(500);
        exec();
    }
};


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

    qDebug() << "thread is "  << QThread::currentThread();

    Work2 work2;
    work2.start();

    //10s后退出
    QThread::sleep(10);
    qDebug() << "main call thread quit";
    work2.exit();
    work2.wait();

    //再次启动
    qDebug() << "start again";
    work2.start();
    //10s后退出
    QThread::sleep(15);
    qDebug() << "main call thread quit";
    work2.exit();
    work2.wait();


    return a.exec();
}

 

你可能感兴趣的:(qt)