Qt中线程的使用

Qt中线程的使用

在qt中线程的使用有两种方式,第一种就是创建一个类继承QObject类,之后使用moveToThread函数将线程添加到类中。另一种就是创建一个类继承QThread类,在类中实现run函数。

第一种方式:

1、首先创建一个自定义的类,继承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);
    }
}

以上代码就是创建的类,在上述的代码中,能看到在头文件中定义了一个slotsFun()槽函数、一个stop()公共函数和一个state私有的成员变量。

slotsFun()槽函数就是我们最终要执行的线程函数。

state私有的成员变量是为了设置线程函数的循环限制,当我们要停止线程退出的时候可以使用公共函数stop设置state为false,这样就退出了线程函数。

这里的stop函数不属于线程,而是属于主线程。

2、启动线程

当我们定义好了线程类之后,就可以在需要启动线程的地方启动线程了。

    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、关闭线程

关闭线程小编使用了很多方式,都没有达到理想的状态,首先是使用QThread中的**terminate**()函数,此函数关闭之后线程中的资源很难释放。因为他是强制的,线程函数无论执行到哪里了都会强制退出线程。

后面就换了中方式,先使用自定义线程类函数退出线程函数,之后再关闭线程类,这样就能很好的释放线程资源了。

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

这里有个小知识点,就是假如我们在自定义的类中定义了俩个槽函数,并且都是在线程启动之后发出信号,那么这两槽函数都是此线程的线程函数,只不过是按发送信号的顺序执行的。

第二种方式

1、创建线程类继承QThread类

#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);
    }

}

以上代码中run就是继承QThread中的虚函数run。使用这中方式启动线程直接调用start函数即可。

2、启动

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、当run函数退出的是后线程就自动结束了。这里和第一种方式不太一样,第一种方式需要使用Qthread中的quit和wait函数。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值