当前位置: 首页 > article >正文

QThread finished Qt::DirectionConnection可能导致start()不会返回的问题

Qt项目中长时间来一直有偶发的界面假死情况,一开始以为是死锁的问题,但遍历代码发现没有重复加锁或循环加锁的情况,为此头发都薅没了,最近偶然情况下发现是QThread使用上的问题,简单介绍如下。

注意以下代码:

QThread* thread = new QThread(this);
connect(thread, SIGNAL(finished()), this, SLOT(stopFinished()), Qt::DirectConnection);

如果采用Qt::DirectConnection,则在stopFinished没有执行完成之前,调用thread->start()不会返回。

可能的情况一:

...
void slotFinished()
{
    while (1) ;
}
...
thread->start(); // 不会返回,在主线程执行则界面假死,在子线程执行则子线程不会结束
...

可能的情况二,该情况出现的概率较低,非常难排查:

...
QMutex m_mutex; // 头文件定义
...
void slotFinished()
{
    ...
    QMutexLocker locker(&this->m_mutex);
    ...
}
...
void test() 
{
    ...
    QMutexLocker locker(&this->m_mutex);
    ...
    // 如果执行到此时,slotFinished执行到QMutexLocker locker(&this->m_mutex),同样会导致与情况一一样的问题
    // 即在主线程执行则导致界面假死,在子线程执行则子线程不会结束。
    thread->start();
    ...
}
...

目前没有深入研究问题的具体原因,但根据以上代码可以轻松模拟出界面假死的情况。

修改方法一:connect方式不指定为Qt::DirectConnection,使用默认方式即可;

修改方法二:针对情况二,可以在thread->start()之前调用this->m_mutex.unlock(),是否能如此修改以实际代码情况确定。


http://www.kler.cn/news/367206.html

相关文章:

  • Pr 视频效果:波形变形
  • 从文化到实践:DevOps的基本概念与核心实践详解
  • ACL访问控制
  • IDEA开发工具使用技巧积累
  • 现在设备普遍切换成TYPE-C适配器后,一拖三数据线接口变革探析
  • 用kali入侵 DarkHole_2测试
  • ️ Vulnhuntr:利用大型语言模型(LLM)进行零样本漏洞发现的工具
  • 【微服务】Java 对接飞书多维表格使用详解
  • 数据分析人员需要掌握sql到什么程度?
  • PHP写一个二维数组排序算法函数可以调用PHP内置函数
  • 【Linux | 网络I/O模型】五种网络I/O模型详解
  • Docker下载途径
  • 【Windows】电脑端口明明没有进程占用但显示端口被占用(动态端口)
  • 正则表达式使用举例一(Python下)
  • 220V降12V1A恒流点灯WT5112
  • 论文笔记(五十一)Challenges for Monocular 6-D Object Pose Estimation in Robotics
  • mysql8数据库备份
  • 合合信息:生成式Al时代的内容安全与系统构建加速,开启智能文档的全新潜能
  • 算法设计与分析——动态规划
  • FPGA学习(7)-线性序列机原理与应用,不同类型的LED控制开关
  • 《复旦学报(自然科学版)》
  • DataSophon集成ApacheImpala的过程
  • 深度学习:神经元(Neuron):人工神经网络中的基本单元
  • Java | Leetcode Java题解之第514题自由之路
  • Java 集合框架是什么?集合框架的优点有哪些?
  • 【nGrinder】性能压测平台记录文档(2)