项目场景:

线程通过继承自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方式,无法停止的问题相关推荐

  1. Qt多线程之 moveToThread的使用

    Qt中使用多线程有两种方式,一种是自定义的class继承于QThread,并重写run函数,在开始线程时,调用start()方法即可.另一种比较灵活的方式,是使用moveToThread()方法,可以 ...

  2. QT 多线程的实现方法以及GUI线程与其他线程间的通信

    GUI线程 Qt应用程序exec后就会生成一个线程,这个线程就是主线程,在GUI程序中也称为GUI线程.主线程也是唯一允许创建QApplication或QCoreAppliation对象,比并且可以对 ...

  3. Qt多线程之继承QObject(moveToThread方式)

    Qt多线程有两两种方式,第一种继承QThread,复写run()函数,但是run()和main()类似,run()函数才是子线程的入口函数,所以在设计到类的操作时,必须把对象或者指针放在run函数里面 ...

  4. Qt 多线程基础及线程使用方式

    文章目录 Qt 多线程操作 2.线程类QThread 3.多线程使用:方式一 4.多线程使用:方式二 5.Qt 线程池的使用 Qt 多线程操作 应用程序在某些情况下需要处理比较复杂的逻辑, 如果只有一 ...

  5. Qt多线程的几种实现方式

    Qt多线程的几种实现方式 在Qt中经常会遇到耗时操作,需要并发执行,这个时候就要用到多线程.Qt的多线程有多种实现形式,这里介绍3种方式. 类实现形式 用类实现多线程是最传统的实现形式,思想是写一个继 ...

  6. Qt多线程编程之moveToThread

    moveToThread方法本质上就是将一个对象放在线程上去执行了 QThread官网文档 moveToThread文档 这里把我认为文档中需要注意的内容摘出来 一定要通过槽函数的形式去调用函数, 要 ...

  7. Qt之线程的使用(moveToThread方式)

    一.本文介绍Qt线程的另一个使用方式,也是Qt官方推荐的方式,即moveToThread方式,楼主的理解就是,就是将这个线程使用方式[Qt之线程的使用(继承QThread重写run函数)]中run函数 ...

  8. Qt多线程-QThread

    版权声明:若无来源注明,Techie亮博客文章均为原创. 转载请以链接形式标明本文标题和地址: 本文标题:Qt多线程-QThread     本文地址:http://techieliang.com/2 ...

  9. Qt多线程编程(一)入门篇

    目录 一.多线程是什么 二.为什么要使用多线程进行开发 1.提高处理效率 2.软件运行更加流畅 3.根据优先级依次处理 三.Qt多线程入门 QThread类,类成员及类成员函数介绍 公有变量 公有函数 ...

最新文章

  1. LeetCode 1115. Print FooBar Alternately--多线程并发问题--Java解法--CyclicBarrier, synchronized, Semaphore 信号量
  2. 连接linux系统软件,Windows系统上有哪些不错的终端软件可以远程连接Linux?
  3. php redis编程,php + redis 实现关注功能
  4. 编写分段函数子函数_编写自己的函数
  5. 局部描述符表LDT的作用+定义+初始化+跳转相关
  6. Ubuntu 配置串口信息
  7. Google面试题—有四个线程1、2、3、4。线程1的功能就是输出1,线程2的功能就是输出2,以此类推.........现在有四个文件ABCD...
  8. win8无法使用内置管理员账户打开的解决方法
  9. 大四阶段的社会实践的主要目的是_大四寒假社会实践报告1500字范文
  10. Apache认证(目录)
  11. 质控工具之TrimGalore使用方法
  12. 易筋SpringBoot 2.1 | 第十九篇:SpringBoot的常用注解
  13. Java 窗口设置图标及背景图片
  14. 抽象代数的代码实现(6)自同构、正规子群、商群
  15. db_recovery_file_dest与log_archive_dest、log_archive_dest_n
  16. win10修改用户名_win10最详细优化设置|win10专业版笔记本优化教程
  17. python提取html表格_python html提取表格数据库数据库
  18. 自动驾驶感知——环境感知的基本概念
  19. CentOS radius 安装
  20. 互联网医院的三个典型样本

热门文章

  1. Python的基础语法(七)(持续更新)
  2. 时事热点新闻简讯汇总 一分钟知晓天下事
  3. C语言实现分数转化为小数(保留三位小数)
  4. 微信小程序与web前端的区别
  5. win10系统cf连接服务器失败,cf与服务器连接失败
  6. 2021年最后一天了,总得留下点什么
  7. 小程序下拉刷新上拉加载 前台+后台
  8. SEO优化平台,常用的4种SEO手段
  9. 『STC8H8K64U』概述
  10. php 当前时间转换成农历,php如何实现公、农历日期的想互转换的实例