qt多线程问题解决


问题背景

使用qt编写多线程程序时,报了以下两个崩溃错误:

  • ASSERT failure in QArrayData::deallocate: “Static data cannot be deleted”, file tools\qarraydata.cpp, line 269
  • ASSERT failure in QWidget: “Widgets must be created in the GUI thread.”, file kernel\qwidget.cpp, line 1007

线程1中有类A,线程2中有类B,类A与类B使用以下槽函数连接:

connect(nvr,&NvrBase::sendNvrRealParam,[=](NvrPlayRealParam param){
 省略GUI操作
    }}
);

一、问题解决

将槽函数改为connect(nvr,&NvrBase::sendNvrRealParam,this[=](NvrPlayRealParam param){

}}

);
当上述槽函数不加this时,代表槽函数内容在信号所在线程执行,而信号所在线程为非gui线程,qt规定,非gui线程不能操作gui线程,故报错;加上this后,程序在this指向的gui线程中执行,故程序正常运行。

二、跨线程间通讯说明

  auto _pollingThread2= new QThread();
  auto pollingProgress= new PollingProgress(this);
  pollingProgress->moveToThread(_pollingThread2);
  //operate信号发射后启动线程工作
  connect(this, SIGNAL(pollingProgress(long,OPERATE)), pollingProgress, SLOT(startPollingProgress(long,OPERATE)));
  //该线程结束时销毁
  connect(_pollingThread2, &QThread::finished,[=]{_pollingThread2->exit(0);delete pollingProgress;delete _pollingThread2;}); //pollingProgress, &QObject::deleteLater);
  _pollingThread2->start();
  _threadQuit=false;
  emit this->pollingProgress(_hDownload,OPERATE::DOWNLOAD);

当槽函数中出现自定义变量时,应加以声明,才能在跨线程间被识别(信号发出线程和信号接收线程是两个线程),声明方法为:
Q_DECLARE_METATYPE(自定义类);
再在信号调用前:
qRegisterMetaType(“自定义类”);
即可使用跨线程信号

二、附:Switch的用法

    while(finished){
        switch(downloadPos)
        {
        case -1:
        {
            Sleep(100);
            break;
        }
        case 200:
        {
            qDebug()<<"下载网络异常情况";
            //finished=true;
            Sleep(100);
            break;
        }
        case 100:
        {
            qDebug()<<"下载完成";
            finished=true;
            //下载后重命名
            QFile::rename(nvr->_pathName+".temp",nvr->_pathName+".dav");
            nvr->stopdownLoad();
            nvr->downloadFinished();
            break;
        }
        default:
                ;
        }}

其中default等同于else,每个case和case间中需要用括号括起来,形成复合语句,如果想在swith中跳出外层循环,只能使用变量,如上图中的//finished=true;

Qt多线程Qt框架提供的一种多线程编程的解决方案,通过创建和管理多个线程,可以实现在程序中同时执行多个任务的能力。Qt提供了QThread类和QtConcurrent命名空间来支持多线程QThread类是Qt提供的多线程编程的基础类,它封装了与底层操作系统调用相关的函数,并提供了一套简单的API来管理线程的生命周期。通过继承QThread类,我们可以创建自己的线程类,并实现线程执行体run()函数。调用线程的start()函数即可启动线程,并在run()函数中实现需要在新线程中执行的任务。另外,QThread类还提供了其他一些方法,如wait()、msleep()等,用于线程的控制。 QtConcurrent命名空间是Qt提供的一个高级多线程编程的工具,其使用起来更加简单方便。QtConcurrent可以运行同步和异步的任务,主要通过函数调用和lambda表达式来实现。我们可以使用QtConcurrent提供的函数,比如map()、filter()等,将任务分解成多个小的任务,并在多个线程中同时执行。使用QtConcurrent,我们只需要关注任务的输入和输出,而无需关注线程的创建和管理。 无论是使用QThread类还是QtConcurrent命名空间,Qt多线程都遵循的原则是将任务分解成小的子任务,并在多个线程中同时执行,以提高程序的性能和响应速度。同时,Qt多线程也提供了线程间的通信机制,例如使用信号与槽机制、使用QMutex、QSemaphore等同步对象来保证数据的正确访问。 需要注意的是,在多线程编程中,我们需要注意线程之间的同步和互斥,以避免资源竞争和数据不一致等问题Qt提供了多种同步和互斥的机制,如互斥锁、条件变量等,可以根据具体的需求选择合适的方式来保证线程之间的安全性。 总之,Qt多线程提供了一种方便易用的多线程编程解决方案,使我们可以在Qt程序中充分利用多核处理器的能力,提高程序的性能和用户体验。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

颢师傅

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值