Qt多线程问题

6 篇文章 0 订阅

这个博客老师讲得好好

Qt中多线程的使用 | 爱编程的大丙 (subingwen.cn) 

Qt实现多线程编程有两种方法:

(一)继承QThread线程类

        重写QThread类中的虚函数QThread::run()实现

(二)继承QObject类

        在我们创建的新类中定义需要在子线程执行的任务函数,在主线程中新建任务类对象与QThread类子线程对象,并通过QObject类提供的moveToThread()方法(画重点!后边要考)将任务类对象移入子线程中。start()启动子线程,并在主线程中通过信号槽机制调用任务类中的任务函数。

  /* 子线程检测人脸 */
    //faceDetect = new FaceDetect(mutex, this);   //PS:指定了父对象的线程,无法实现任务的移入
    faceDetect = new FaceDetect(mutex);
    thread = new QThread(this);
    faceDetect->moveToThread(thread);
    thread->start();
    connect(this, &AttendanceClient::sendCamImage, faceDetect, &FaceDetect::detect);

注意:

        由于Qt的对象树机制,父对象析构时,会先释放其子对象的资源,所以我们在窗口主线程定义类对象时,习惯指定其父对象(这里的父对象和父类不同),以期自动释放资源。但是,不能为将要移入子线程的类对象指定父对象!因为将任务类对象移入子线程的操作是从任务类的父类QObject类中继承的,若为任务对象指定父对象,则会出现以下警告,并在主线程中执行任务函数。

警告: 

QObject::moveToThread: Cannot move objects with a parent

        我在调试代码的时候,就因为打印的日志信息,忽略了这个警告,导致任务函数执行在主线程中,又因为我在子线程和主线程中均需访问主线程中的一个共享资源,来表示当前检测的状态,故我在子线程与主线程涉及的代码上下文处加了QMutex互斥锁(当然也可以用信号槽机制),结果显而易见了,由于子线程移入失败,我实际是在主线程中加了两把锁,死锁成立,程序阻塞崩溃- -。

贴士:

1.  同线程、跨线程中值传递、引用传递、指针传递区别

  • 在一个线程中,Qt信号槽通信形参值传递、引用传递有区别。值传递会复制对象,引用传递不会;
  • 在不同线程中,利用Qt信号槽跨线程通信时(默认QueuedConnection),值传递、引用传递均会复制对象。

        所以这里子线程跨线程访问主线程栈区变量,需要用指针传递

2.利用信号槽机制跨线程通信,需要自定义类型注册

    // 在Qt信号槽中使用自定义类型,需要注意使用qRegisterMetaType对自定义类型进行注册(尤其在跨线程通信中)
    qRegisterMetaType<Mat>("Mat");
    qRegisterMetaType<cv::Mat>("cv::Mat");
    qRegisterMetaType<int>("int*");
    qRegisterMetaType<vector<cv::Rect>>("vector<cv::Rect>");

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值