QT多线程的实现方式:QThread run优雅的创建与退出【QT多线程】

您所在的位置:网站首页 实现多线程方法的目的和意义是什么 QT多线程的实现方式:QThread run优雅的创建与退出【QT多线程】

QT多线程的实现方式:QThread run优雅的创建与退出【QT多线程】

2024-05-30 09:00| 来源: 网络整理| 查看: 265

qt通过继承实现线程的方法有两种

继承QThread,然后重写run函数实现多线程继承QObject,使用moveToThread函数实现多线程

本文介绍第一种的创建、使用与退出。

一、QThread类的run介绍 1、QThread::run函数的使用

QThread 是用来管理线程的,它所依附的线程和它管理的新线程并不是同一个东西QThread 所依附的线程,就是执行创建QThread的线程。也就是咱们这儿的主线程,QThread 管理的新线程,就是 run 启动的线程。

所以总结一句话:QThread只有run函数是在新线程里的,其他所有函数都在QThread生成的线程里

那么就抛出两个问题

1.QThread的对象依附在主线程中,次线程的slot函数会在主线程中执行,而不是次线程。除非:(不建议这样做)

QThread 对象通过movetoThread依附到次线程中(这里涉及到实现多线程的第二种方式)slot 和信号是直接连接,且信号在次线程中发射(这里涉及到QTconnect的第五个参数)

2.QThread的继承类的其他函数尽量别要有太耗时的操作,要确保所有耗时的操作都在run函数里

2、QThread run方式特点

2.1优点:可以通过信号槽与外界进行通信。 2.2缺点:

每次新建一个线程都需要继承QThread,实现一个新类,使用不太方便。 要自己进行资源管理,线程释放和删除。并且频繁的创建和释放会带来比较大的内存开销。

2.3适用场景:QThread适用于那些常驻内存的任务。

二、QThread run实现一个简单线程

新建一个集成QThread的类,重写虚函数run,通过run启动线程

代码:https://download.csdn.net/download/qq_43445867/88332781

1、基本流程 #ifndef QTHREAD_RUN_H #define QTHREAD_RUN_H class QThread_Run { public: QThread_Run(); }; #endif // QTHREAD_RUN_H

1.1需要创建一个线程类的子类,让其继承 QT 中的线程类 QThread,比如:

#ifndef QTHREAD_RUN_H #define QTHREAD_RUN_H #include class QThread_Run : public QThread { Q_OBJECT public: explicit QThread_Run(QObject *parent = nullptr); QThread_Run(); }; #endif // QTHREAD_RUN_H

 1.2 重写父类的 run () 方法,在该函数内部编写子线程要处理的具体的业务流程

#ifndef QTHREAD_RUN_H #define QTHREAD_RUN_H #include class QThread_Run : public QThread { Q_OBJECT public: explicit QThread_Run(QObject *parent = nullptr); QThread_Run(); protected: void run(); }; #endif // QTHREAD_RUN_H

1.3 在主线程中创建子线程对象,new 一个就可以了

QThread_Run* qthread_run=new QThread_Run(this);

1.4 启动子线程,调用 start () 方法

qthread_run->start();

不能在类的外部调用 run () 方法启动子线程,在外部调用 start () 相当于让 run () 开始运行

2、完整代码

qthread_run.h

#ifndef QTHREAD_RUN_H #define QTHREAD_RUN_H #include class QThread_Run : public QThread { Q_OBJECT public: explicit QThread_Run(QObject *parent = nullptr); QThread_Run(); protected: void run(); signals: void result(int); }; #endif // QTHREAD_RUN_H

qthread_run.c

#include "qthread_run.h" #include #include QThread_Run::QThread_Run(QObject *parent): QThread(parent) { } void Delay_MSec(unsigned int msec) { QEventLoop loop;//定义一个新的事件循环 QTimer::singleShot(msec, &loop, SLOT(quit())); //创建单次定时器,槽函数为事件循环的退出函数 loop.exec(); //事件循环开始执行,程序会卡在这里,直到定时时间到,本循环被退出 } void QThread_Run::QThread_Run::run() { for(int i=0;isetupUi(this); QThread_Run* qthread_run=new QThread_Run(this); connect(qthread_run,&QThread_Run::result,this,[=](int num) { ui->lcdNumber->display(num); }); connect(ui->pushButton,&QPushButton::clicked, this, [=]() { qthread_run->start(); }); } MainWindow::~MainWindow() { delete ui; }

mainwindow.h

#ifndef MAINWINDOW_H #define MAINWINDOW_H #include #include "qthread_run.h" QT_BEGIN_NAMESPACE namespace Ui { class MainWindow; } QT_END_NAMESPACE class MainWindow : public QMainWindow { Q_OBJECT public: MainWindow(QWidget *parent = nullptr); ~MainWindow(); private: Ui::MainWindow *ui; }; #endif // MAINWINDOW_H 三、优雅的停止创建的线程

quit和exit函数都不会中途终端线程,要马上终止一个线程可以使用terminate函数,但这个函数存在非常不安定因素,会提示以下错误

QObject::killTimer: Timers cannot be stopped from another thread

停止创建的线程分两种情况

1、不使用事件循环

run函数内有一个 while 或 for 的死循环

最简单的方法是添加一个bool变量,设置一个标记来控制死循环的退出,通过主线程修改这个bool变量来进行终止,但这样有可能引起访问冲突,需要加锁

完整代码:https://download.csdn.net/download/qq_43445867/88332782

需要在原来的头文件加上如下语句

 qthread_run.h

#ifndef QTHREAD_RUN_H #define QTHREAD_RUN_H #include class QThread_Run : public QThread { Q_OBJECT public: explicit QThread_Run(QObject *parent = nullptr); QThread_Run(); bool m_isCanRun;//加入标志位 //加入槽函数 public slots: void stopImmediately(); protected: void run(); signals: void result(int); }; #endif // QTHREAD_RUN_H

修改源文件以及run函数

 qthread_run.c

#include "qthread_run.h" #include #include QThread_Run::QThread_Run(QObject *parent): QThread(parent) { } void Delay_MSec(unsigned int msec) { QEventLoop loop;//定义一个新的事件循环 QTimer::singleShot(msec, &loop, SLOT(quit())); //创建单次定时器,槽函数为事件循环的退出函数 loop.exec(); //事件循环开始执行,程序会卡在这里,直到定时时间到,本循环被退出 } //增加槽函数处理 void QThread_Run::stopImmediately() { QMutexLocker locker(&m_lock); m_isCanRun = false; } void QThread_Run::QThread_Run::run() { for(int i=0;i


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3