Qt使用moveToThread( )正确的开启多线程、安全的退出线程

Qt中开启多线程有两种方式,一种是重构run函数,另一种是moveToThread的方式,这里我主要介绍一下moveToThread,这是Qt4.8后新增的功能,也是Qt开发者极力推荐使用的多线程方式。

首先需要为子线程单独创建一个类,继承QObject。
在这里插入图片描述
如上图,让耗时函数在worker类中执行。

之后在主线程引用此类的头文件和QThread,并实例化耗时类对象和线程对象。

#include <QThread>
#include "worker.h"

QThread my_thread;
Worker *my_worker= new Worker;//实例化耗时类
my_worker->moveToThread(&my_thread);//开辟子线程,将耗时类放入子线程中去

接下来是连接信号与槽:
信号与槽函数自行在对应头文件中定义。

connect(&my_thread,&QThread::finished,my_worker,&QObject::deleteLater);//线程析构
connect(this,&Widget::sig_start,my_worker,&Worker::slot_start);//启动线程

连接好信号与槽后,就可以正式开启子线程了:

my_thread.start();//调用线程
emit this->sig_start();//启动线程信号

因为子线程的开启和析构会占用大量资源,所以一般来说子线程会以循环的方式持续执行,那么循环的退出就至关重要了,不然当关闭程序时要么出现程序假死或者程序关闭但是线程还在持续执行的现象。

我的方法是给子线程的循环设置入口标志位及出口标志位:

#include "worker.h"
volatile bool start=1;//线程标志位
void Worker::slot_start()
{
     for(;;)
     {
          if(start==1)//标志位=1,循环执行耗时函数
          {     
               ......//耗时函数
          }
          else//标志位=0,跳出循环,线程执行结束
          {
               break;
          }
     }
}

当析构时,设置线程标志位=0,等待线程完成当前循环,并退出线程。

my_worker->start=0;//子线程标志位=0,线程跳出循环
my_thread.quit();
my_thread.wait();//退出线程,并等待线程完成当前循环
  • 11
    点赞
  • 74
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
Qt中的多线程可以使用`QThread`类来实现,而`moveToThread`是一个很常用的函数,用于将一个QObject对象移动到另一个线程中执行。 下面是一个使用`moveToThread`的简单例子: ```cpp #include <QCoreApplication> #include <QThread> #include <QDebug> class Worker : public QObject { Q_OBJECT public: Worker(QObject *parent = nullptr) : QObject(parent) {} public slots: void doWork() { qDebug() << "Worker thread:" << QThread::currentThreadId(); } }; int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); Worker worker; QThread thread; worker.moveToThread(&thread); QObject::connect(&thread, &QThread::started, &worker, &Worker::doWork); QObject::connect(&worker, &Worker::destroyed, &thread, &QThread::quit); thread.start(); return a.exec(); } ``` 在上面的例子中,我们创建了一个`Worker`类,它继承自`QObject`类,并有一个`doWork`槽函数。我们将`worker`对象通过`moveToThread`函数移动到了`thread`线程中。然后,我们通过`connect`函数将`thread`的`started`信号连接到`worker`的`doWork`槽函数上,当线程启动时,`doWork`槽函数会在`thread`线程中执行。同时,我们还将`worker`的`destroyed`信号连接到`thread`的`quit`槽函数上,以保证线程能够正确退出。 需要注意的是,如果我们将一个QObject对象移动到了另一个线程中执行,那么它的所有信号和槽函数都必须在该线程中执行,否则会出现问题。所以,在上面的例子中,我们将`worker`对象的`doWork`槽函数定义为`public slots`,并且在`thread`线程中执行,以保证它能正确执行。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值