【调试记录】QT中使用多线程导致的死锁

news/2024/12/28 21:35:40/

示例代码

#include <QApplication>
#include <QWidget>
#include <QTimer>
#include <thread>
#include <mutex>using namespace std::chrono_literals;class Window : public QWidget{
public:Window(QWidget *parent = nullptr): QWidget(parent), count_{} {// 启动工作线程thd_ = std::jthread([this](std::stop_token st) {while(!st.stop_requested()) {std::this_thread::sleep_for(100ms);std::lock_guard lg(mtx_);QMetaObject::invokeMethod(this, [this](){ qDebug() << "invokeMethod:" << ++count_; }, Qt::BlockingQueuedConnection);}});// 定时器auto* timer{ new QTimer(this) };connect(timer, &QTimer::timeout, this, [this]() {std::lock_guard lg(mtx_);qDebug() << "timeout:" << ++count_;});timer->start(40);}~Window() = default;private:size_t count_;std::mutex mtx_;std::jthread thd_;
};int main(int argc, char *argv[]) {QApplication a(argc, argv);Window w;w.show();return a.exec();
}

运行结果

invokeMethod: 1
timeout: 2
timeout: 3
timeout: 4
invokeMethod: 5
timeout: 6
timeout: 7

原因分析

原因在于第18行采用阻塞队列的连接方式。

QMetaObject::invokeMethod(this, [this](){ qDebug() << "invokeMethod:" << ++count_; }, Qt::BlockingQueuedConnection);

子线程在第17行获取到锁,主线程刚好运行到24行准备获取锁。此时子线程执行第18行,阻塞调用等待主线程执行qDebug() << "invokeMethod:" << ++count_;完成。
子线程已经获取到锁,主线程等待获取锁,子线程又等待主线程事件循环执行函数,由此产生死锁。

解决方案

方案一:将18行阻塞调用改为非阻塞调用

QMetaObject::invokeMethod(this, [this](){ qDebug() << "invokeMethod:" << ++count_; });

方案二:在锁外调用(仅适用于无数据竞争的情况,或采用原子变量),即去掉第17行的加锁。


http://www.ppmy.cn/news/42453.html

相关文章

tocbot生成文章目录

学习链接 github上的tocbot npmjs上的tocbot 效果图 使用步骤 1. 安装tocbot npm install tocbot --save2. vue组件中使用引入tocbot 只需要引入tocbot&#xff0c;然后调用tocbot.init(…)&#xff0c;指定提取的文章内容所在的dom&#xff0c;以及要把生成的目录放到哪个…

数据分析师 ---- SQL强化(2)

数据分析师 ---- SQL强化(2) 文章目录数据分析师 ---- SQL强化(2)题目一&#xff1a;SQL实现文本处理题目二&#xff1a;语种播放量前三高所有歌曲总结&#xff1a;题目一&#xff1a;SQL实现文本处理 现有试卷信息表examination_info&#xff08;exam_id试卷ID, tag试卷类别,…

验证码识别过程中切割图片的几种方案

目录 方案一&#xff1a;图片均分 方案二&#xff1a;寻找轮廓并截取 方案三&#xff1a;聚类算法 方案四&#xff1a;垂直投影法 源码下载 在用机器学习识别验证码的过程中&#xff0c;我们通常会选择把验证码中的各个字符切割出来然后单独识别&#xff0c;切割质量会直接…

Leetcode.2521 数组乘积中的不同质因数数目

题目链接 Leetcode.2521 数组乘积中的不同质因数数目 Rating &#xff1a; 1413 题目描述 给你一个正整数数组 nums&#xff0c;对 nums所有元素求积之后&#xff0c;找出并返回乘积中 不同质因数 的数目。 注意&#xff1a; 质数 是指大于 1 且仅能被 1 及自身整除的数字。…

linux替换jar中的文件(小修改,大修改还是整包发布稳妥)

当我们上线某个应用发现有个小bug需要修改,而且改动的地方并不是很多,比如,修改application.yml文件或者替换几个class文件,此时如果找到源文件修改后重新打包替换重启有点繁琐,就可以使用此方式修改。 目录 修改配置文件 修改class文件 附录:jar的命令 修改配置文件 …

一文快速回顾 Servlet、Filter、Listener

什么是Servlet&#xff1f; 前置知识&#xff1a; Web 服务器&#xff1a;可以指硬件上的&#xff0c;也可以指软件上的。从硬件的角度来说&#xff0c; Web 服务器指的就是一台存储了网络服务软件的计算机&#xff1b;从软件的角度来说&#xff0c; Web 服务器指的是一种软件…

【Python搞笑游戏】因蔡徐坤打篮球动作超火,被某程序员写成了一款游戏,画面美到不敢看,成功学到了精髓~(附源码免费)

导语 之前网络最火的梗&#xff0c;非“C徐坤打篮球”莫属。个人感觉&#xff0c;只有多年前的“春哥纯爷们”堪与匹敌&#xff01; 虽然说C徐坤打篮球是一个老梗了&#xff0c;但是确实非常搞笑&#xff0c;今天就跟着小编一起来回忆一下吧&#xff01; “我是练习两年半的…

creator-assetbundle分包

title: creator-assetbundle分包 categories: Cocos2dx tags: [creator, 分包, assetbundle] date: 2023-04-10 15:55:22 comments: false mathjax: true toc: true creator-assetbundle分包 前篇 Asset Bundle 介绍 - https://docs.cocos.com/creator/manual/zh/asset/bundle…