QT 多线程使用moveToThread方式,无法停止的问题
项目场景:
线程通过继承自QObject,使用moveToThread及start方式开启。
问题描述
主函数中通过信号槽连接,线程工作函数能够正常运行,通过原子变量std::atomic<bool>控制循环启停,但无法正常关闭。
#include <QCoreApplication>int main(int argc, char *argv[])
{QCoreApplication a(argc, argv);AudioWSServer audioServer;QThread *videoThread = new QThread;VideoWSClient *videoClient = new VideoWSClient;videoClient->moveToThread(videoThread);videoThread->start();QObject::connect(&audioServer, &AudioWSServer::startVideoSignal, videoClient, &VideoWSClient::startVideoSlot, Qt::QueuedConnection);QObject::connect(&audioServer, &AudioWSServer::stopVideoSignal, videoClient, &VideoWSClient::stopVideoSlot);return a.exec();
}
原因分析:
主线程中 QObject::connect(&audioServer, &AudioWSServer::stopVideoSignal, videoClient, &VideoWSClient::stopVideoSlot) 默认选取Qt::QueuedConnection方式暂停线程工作函数。线程工作函数startVideoSlot()中一直处理耗时任务,造成槽函数一直无法触发。
官方说明文档:
The slot is invoked when control returns to the event loop of the receiver's thread. The slot is executed in the receiver's thread.
解决方案:
通过Qt::DirectConnection方式暂停线程工作处理函数。
QObject::connect(&audioServer, &AudioWSServer::stopVideoSignal, videoClient, &VideoWSClient::stopVideoSlot, Qt::DirectConnection);
或通过lambda表达式进行处理
QObject::connect(&audioServer, &AudioWSServer::stopVideoSignal, [=]()
{videoClient->stopVideoSlot();
});
注:通过该种方式暂停线程处理函数,不可在stopVideoSlot()函数中关闭由子线程创建的QWebsocket对象。否则会报段错误。造成该现象的原因为:stopVideoSlot()函数线程的所有权属于信号发送的线程,本项目中属于主线程。QWebsocket对象不允许跨线程使用。
解决方法:
通过在创建的线程处理函数中对QWebSocket对象进行关闭。
eg:
void VideoWSClient::startVideoSlot()
{m_bIsStart = true;m_pVideoWSClient = new QWebSocket;//m_pVideoWSClient为QWebSocket对象while(m_bIsStart ){QThread::sleep(1);}m_pVideoWSClient->deleteLater();m_pVideoWSClient = nullptr;
}
QT 多线程使用moveToThread方式,无法停止的问题相关推荐
- Qt多线程之 moveToThread的使用
Qt中使用多线程有两种方式,一种是自定义的class继承于QThread,并重写run函数,在开始线程时,调用start()方法即可.另一种比较灵活的方式,是使用moveToThread()方法,可以 ...
- QT 多线程的实现方法以及GUI线程与其他线程间的通信
GUI线程 Qt应用程序exec后就会生成一个线程,这个线程就是主线程,在GUI程序中也称为GUI线程.主线程也是唯一允许创建QApplication或QCoreAppliation对象,比并且可以对 ...
- Qt多线程之继承QObject(moveToThread方式)
Qt多线程有两两种方式,第一种继承QThread,复写run()函数,但是run()和main()类似,run()函数才是子线程的入口函数,所以在设计到类的操作时,必须把对象或者指针放在run函数里面 ...
- Qt 多线程基础及线程使用方式
文章目录 Qt 多线程操作 2.线程类QThread 3.多线程使用:方式一 4.多线程使用:方式二 5.Qt 线程池的使用 Qt 多线程操作 应用程序在某些情况下需要处理比较复杂的逻辑, 如果只有一 ...
- Qt多线程的几种实现方式
Qt多线程的几种实现方式 在Qt中经常会遇到耗时操作,需要并发执行,这个时候就要用到多线程.Qt的多线程有多种实现形式,这里介绍3种方式. 类实现形式 用类实现多线程是最传统的实现形式,思想是写一个继 ...
- Qt多线程编程之moveToThread
moveToThread方法本质上就是将一个对象放在线程上去执行了 QThread官网文档 moveToThread文档 这里把我认为文档中需要注意的内容摘出来 一定要通过槽函数的形式去调用函数, 要 ...
- Qt之线程的使用(moveToThread方式)
一.本文介绍Qt线程的另一个使用方式,也是Qt官方推荐的方式,即moveToThread方式,楼主的理解就是,就是将这个线程使用方式[Qt之线程的使用(继承QThread重写run函数)]中run函数 ...
- Qt多线程-QThread
版权声明:若无来源注明,Techie亮博客文章均为原创. 转载请以链接形式标明本文标题和地址: 本文标题:Qt多线程-QThread 本文地址:http://techieliang.com/2 ...
- Qt多线程编程(一)入门篇
目录 一.多线程是什么 二.为什么要使用多线程进行开发 1.提高处理效率 2.软件运行更加流畅 3.根据优先级依次处理 三.Qt多线程入门 QThread类,类成员及类成员函数介绍 公有变量 公有函数 ...
最新文章
- LeetCode 1115. Print FooBar Alternately--多线程并发问题--Java解法--CyclicBarrier, synchronized, Semaphore 信号量
- 连接linux系统软件,Windows系统上有哪些不错的终端软件可以远程连接Linux?
- php redis编程,php + redis 实现关注功能
- 编写分段函数子函数_编写自己的函数
- 局部描述符表LDT的作用+定义+初始化+跳转相关
- Ubuntu 配置串口信息
- Google面试题—有四个线程1、2、3、4。线程1的功能就是输出1,线程2的功能就是输出2,以此类推.........现在有四个文件ABCD...
- win8无法使用内置管理员账户打开的解决方法
- 大四阶段的社会实践的主要目的是_大四寒假社会实践报告1500字范文
- Apache认证(目录)
- 质控工具之TrimGalore使用方法
- 易筋SpringBoot 2.1 | 第十九篇:SpringBoot的常用注解
- Java 窗口设置图标及背景图片
- 抽象代数的代码实现(6)自同构、正规子群、商群
- db_recovery_file_dest与log_archive_dest、log_archive_dest_n
- win10修改用户名_win10最详细优化设置|win10专业版笔记本优化教程
- python提取html表格_python html提取表格数据库数据库
- 自动驾驶感知——环境感知的基本概念
- CentOS radius 安装
- 互联网医院的三个典型样本