Qt多线程的两种创建方法以及快速停止线程方法

6 篇文章 0 订阅
1 篇文章 0 订阅

文章目录

目录

文章目录

前言

一、多线程的两种创建方法

1.继承QThread

2.moveToThread方法

二、多线程快速停止

1.线程停止介绍

2.具体实现 

总结


前言

介绍多线程的两种创建方法以及快速停止线程的方法

一、多线程的两种创建方法

1.继承QThread

1.自定义一个类,继承于QThread。

class MyThread:public QThread{
public:
     virtual void run() override;	//虚函数  线程处理函数(和主线程不在同一个线程)
    
signals:
    void Finshed();	//信号 线程执行完发送
}
void MyThread::run() {
    // 实现  -- 复杂的处理过程
    
    emit Finished;	// 发送线程
};

 2.定义线程

MyThread mythread;
//MyThread* mythread = new MyThread();

 3.开启线程

mythread.start();
//mythread->start();

 通过执行mythread.start()或者mythread->start()启动run()函数,而不是直接调用run()函数。

4.自定义线程结束槽函数

run()函数结束前会发送 Finished信号,可以自定义槽函数打印线程结束;

public slots:
	void SlotFinished();
——————————————————————
void MyWidget::SlotFinished(){
    // 线程结束后的操作
    qDebug() << "子线程结束!";
}

5.绑定线程结束信号和线程结束槽

connect(&mythread,&MyThread::Finished,this,&MyWidget::SlotFinished);
//connect(mythread,&MyThread::Finished,this,&MyWidget::SlotFinished);

【提示】MyThread类可以自定义多种方法,在run()函数内执行。 

class MyThread:public QThread{
public:
   virtual void run() override;	//虚函数  线程处理函数(和主线程不在同一个线程)

    void Func1();//方法1
    void Func2();//方法2
signals:
    void Finshed();	//信号 线程执行完发送
}
void MyThread::run() {
    // 实现  -- 复杂的处理过程
    Func1();
    Func2();

    emit Finished;	// 发送线程
};

2.moveToThread方法

 1.自定义一个功能实现类。

#ifndef THREAD_H
#define THREAD_H
 
#include <QObject>
 
class MyThread :public QObject
{
    Q_OBJECT
public:
    MyThread();
    ~Mythread();

    void Func1();
    void Func2();
};
 
#endif // THREAD_H

2.mythread.cpp中去完善构造函数与功能函数的具体实现。 

#include "mythread.h"
#include <QDebug>
Thread::Thread()
{
    
}
 
void MyThread::Func1()
{
    qDebug()<<"方法1";
}

void MyThread::Func2()
{
    qDebug()<<"方法2";
}

3. 在你的窗口mywidget.h中添加各种头文件,创建两个信号,声明一个线程和刚刚创建的自定义功能实现类,添加两个按钮,声明两个响应按钮的槽函数。

#ifndef MYWIDGET_H
#define MYWIDGET_H
 
#include <QWidget>
#include <QThread>
#include <QObject>
#include "thread.h"
#include <QtWidgets/QPushButton>
 
namespace Ui {
class MyWidget ;
}
 
class MyWidget : public QWidget
{
    Q_OBJECT
 
public:
    MyWidget (QWidget *parent = 0);
    ~MyWidget ();

public slots:
    void SlotDoFunc1();
    void SlotDoFunc2();

signals:
    void RunFunc1(); // 信号
    void RunFunc2(); 
 
private:
    Ui::MyWidget *ui;
    QThread *Thread;//qt的线程类
    MyThread *Mythread;//自定义的功能实现类

    QPushButton* Func1QPushButton;//执行方法1按钮
    QPushButton* Func2QPushButton;//执行方法2按钮
};
 
#endif // MYWIDGET_H

 4.在mywidget.cpp中,先实例化Thread线程和Mythread,并且把Mythread这个类推向子线程,代码如下:

#include "mywidget.h"
#include "ui_mywidget.h"
 
MyWidget::MyWidget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::MyWidget)
{
    ui->setupUi(this);

    Thread = new QThread;
    Mythread = new MyThread;

    connect(this,&MyWidget::RunFunc1,Mythread ,&Mythread::Func1);
    connect(this,&MyWidget::RunFunc2,Mythread ,&Mythread::Func2);

    Mythread->moveToThread(Thread);
    connect(ui->Func1QPushButton, SIGNAL(clicked()), this, SLOT(SlotDoFunc1()));
    connect(ui->Func2QPushButton, SIGNAL(clicked()), this, SLOT(SlotDoFunc2()));
}

void MyWidget::SlotDoFunc1()
{
    //线程开启之前需要等之前的线程结束
	if (Thread->isRunning())
	{
		wait();
	}
    emit RunFunc1();
    Thread->start();
}

void MyWidget::SlotDoFunc2()
{
    //线程开启之前需要等之前的线程结束
	if (Thread->isRunning())
	{
		wait();
	}
    emit RunFunc2();
    Thread->start();
}
 
MyWidget::~MyWidget()
{
    delete ui;
}

二、多线程快速停止

1.线程停止介绍

子线程停止标志是run()函数运行结束,quit()、stop()【terminate()没试过,但是不建议使用,会出现内存问题】等并不会立刻停止run(),只是告诉线程要停止,真正停止还是需要等run()函数执行完毕。想快速停止必须要自定义方法,给出停止标志。以第一种创建多线程方法为例,具体操作如下:

2.具体实现 

 1.在线程类中,声明一个bool值的停止标志,以及停止函数。

class MyThread:public QThread{
    
    Q_OBJECT

public:
    MyThread();
    ~MyThread();

public:
     virtual void run() override;	//虚函数  线程处理函数(和主线程不在同一个线程)

public:
    void Stop();//停止函数

signals:
    void Finshed();	//信号 线程执行完发送
}

private:
    bool m_bStop;//停止标志

2.在mythread.cpp的构造函数中初始化m_bStop为false,Stop方法中用来设置m_bStop的值。

MyThread::MyThread()
: QThread()
{
    m_bStop = false;
}
void MyThread::Stop()
{
    m_bStop = true;
}

3. 在run()函数的耗时的循环中加判断,退出循环。

void MyThread::run()
{
    //m_bStop = false;//如果线程未被delete且多次停止启用需要
加这句保证循环开始时m_bStop始终为false,否则第二次开启将不会进入循环。
    for(int i, i< 10000, i++)
    {
        if(m_bStop)
        {
            return;
        }
        //复杂的计算
    }
    emit Finished;	// 发送线程
}

4.在需要停止线程的地方,调用线程类的Stop()方法即可。 

void MyWidget::Func()
{
    MyThread myThread;
    myThread.Stop();
   // MyThread* myThread = new MyThread();
   // myThread->Stop();
}

如果在run()函数中调用线程类本身自定义的方法,方法中有耗时的循环,可类推。代码如下: 

class MyThread:public QThread{
public:
   virtual void run() override;	//虚函数  线程处理函数(和主线程不在同一个线程)

    void Func();//线程类本身自定义方法
signals:
    void Finshed();	//信号 线程执行完发送
}

void MyThread::run() {

    m_bStop = false;
    Func();//实现线程类本身自定义方法
    emit Finished;	// 发送线程
};

void MyThread::Func() {

    for(int i, i< 10000, i++)
    {
        if(m_bStop)
        {
            return;
        }
        //复杂的计算
    }
};

总结

正在学习中,欢迎批评指正!

  • 13
    点赞
  • 41
    收藏
    觉得还不错? 一键收藏
  • 12
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值