The use of threads in Qt

The use of threads in Qt

There are two ways to use threads in Qt. The first is to create a class that inherits the QObject class, and then use the moveToThread function to add threads to the class. The other is to create a class that inherits the QThread class and implements the run function in the class.

First way:

1. First create a custom class that inherits QObject.

#ifndef THREAD001_H
#define THREAD001_H

#include <QObject>

class MyThread : public QObject
{
    Q_OBJECT
public:
    explicit MyThread(QObject *parent = nullptr);
    void stop();

private:
    bool state = false;

signals:

public slots:
    void slotsFun(QString number);
};

#endif // THREAD001_H
#include "mythread.h"
#include <QDebug>
#include <QThread>
MyThread::MyThread(QObject *parent) : QObject(parent)
{

}

void MyThread::stop()
{
    state = false;
    qDebug()<<"Thread001::stop() 当前线程号:"<< QThread::currentThreadId();
}

void MyThread::slotsFun(QString number)
{
    qDebug()<<"父线程号:"<<number;
    qDebug()<<"当前线程号:"<< QThread::currentThreadId();
    state = true;
    static int i = 0;
    while(state){
        qDebug()<<"i的数值:"<<i <<"   state = "<<state;
        i++;
        QThread::sleep(1);
    }
}

The above code is the created class. In the above code, you can see that a slotsFun() slot function, a stop() public function and a state private member variable are defined in the header file.

The slotsFun() slot function is the thread function we ultimately want to execute.

The private member variable of state is used to set the loop limit of the thread function. When we want to stop the thread from exiting, we can use the public function stop to set state to false, thus exiting the thread function.

The stop function here does not belong to the thread, but to the main thread.

2. Start the thread

After we define the thread class, we can start the thread where we need to start the thread.

    QThread* m_thread = nullptr;//这个是qt的线程类
    MyThread* m_mythread = nullptr;//这个是我们自定义的线程类
void MainWindow::on_btn_create_clicked()
{
    if(m_thread == nullptr){
        m_thread = new QThread();//实例化线程对象
        m_mythread = new MyThread();//实例化自定义的线程对象
        m_mythread->moveToThread(m_thread);//线程绑定
        //线程结束函数信号槽,用于当线程结束之后释放资源。
        connect(m_thread,&QThread::finished,this,[=](){
            qDebug()<<"m_thread001 线程执行结束";
            m_thread->deleteLater(); //释放线程资源
            m_thread = nullptr;
            m_mythread->deleteLater();//释放自定定义的线程类资源
            m_mythread = nullptr;

        });
        //启动线程之后,线程发出的信号
        connect(m_thread,&QThread::started,this,[=](){
            qDebug()<<"m_thread001 线程执行启动";
        });
        //调用线程函数,线程启动之后,还需要调用一下自定义线程类中槽函数
        connect(this,&MainWindow::startThreadFun,m_mythread,&MyThread::slotsFun);
    }

}
void MainWindow::on_btn_start_clicked()
{
    //启动线程
    m_thread->start();
    qDebug()<<"主线程id:"<<QThread::currentThreadId();
    //发送信号调用槽函数
    emit startThreadFun("看上面的主线程id");
}

3. Close the thread

The editor has used many methods to close the thread, but none of them have reached the ideal state. The first is to use the ** terminate **() function in QThread. After this function is closed, it is difficult to release the resources in the thread. Because it is mandatory, the thread function will force the thread to exit no matter where it is executed.

Later, I changed to the middle method, first using the custom thread class function to exit the thread function, and then closing the thread class, so that the thread resources can be released well.

void MainWindow::on_btn_stop_clicked()
{
    m_mythread->stop();
    m_thread->quit();
    m_thread->wait();
}

A little knowledge point here is that if we define two slot functions in a custom class, and both send signals after the thread starts, then these two slot functions are the thread functions of this thread, but they are The order in which signals are sent is executed.

Second way

1. Create a thread class that inherits the QThread class

#ifndef MYTHREAD2_H
#define MYTHREAD2_H

#include <QThread>
#include <QDebug>
class MyThread2 : public QThread
{
public:
    MyThread2();
    void stop();

    void run() override;
private:
    bool state = false;
};

#endif // MYTHREAD2_H

#include "mythread2.h"

MyThread2::MyThread2()
{

}

void MyThread2::stop()
{
    state = false;
    qDebug()<<"Thread001::stop() 当前线程号:"<< QThread::currentThreadId();
}

void MyThread2::run()
{
    qDebug()<<"当前线程号:"<< QThread::currentThreadId();
    state = true;
    static int i = 0;
    while(state){
        qDebug()<<"slotsFuni的数值:"<<i <<"   state = "<<state;
        i++;
        QThread::sleep(1);
    }

}

In the above code, run inherits the virtual function run in QThread. Use this method to start the thread and directly call the start function.

2. Start

void MainWindow::on_btn_start_clicked()
{
    if(m_mythread2 == nullptr){
        m_mythread2 = new MyThread2();
        connect(m_mythread2,&QThread::finished,this,[=](){
                qDebug()<<"m_mythread2 线程执行结束";
                m_mythread2->deleteLater();
                m_mythread2 = nullptr;
                });
    }
    m_mythread2->start();//启动线程
}

3. When the run function exits, the thread ends automatically. This is not the same as the first method. The first method requires using the quit and wait functions in Qthread.

Guess you like

Origin blog.csdn.net/qq_43812868/article/details/131980392