news 2026/6/2 5:55:04

Qt多线程阻塞:为何信号失效?

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Qt多线程阻塞:为何信号失效?

这个问题问到了 Qt 多线程编程的核心机制。简单来说,是因为“一个线程在同一时刻只能做一件事”

为了让你彻底理解,我们把线程想象成一个**“办事员”,把事件循环想象成他的“工作手册”**。

1. 正常的“事件驱动”模式

在正常的 Qt 线程中,办事员的操作流程是这样的(这就是exec()内部做的事):

// 简化版的事件循环逻辑 (QEventLoop) while (true) { // 1. 检查有没有新邮件(信号、定时器、鼠标点击等事件) Event e = waitNextEvent(); // 2. 拆开邮件,根据指令去干活 processEvent(e); // 3. 干完活了,回到第 1 步继续等 }

在这种情况下,办事员大部分时间都在等邮件。一旦你从主线程发一个QueuedConnection的信号,就相当于给他的邮箱丢了一封信。他处理完手头的微小工作后,马上就会拆信并执行setPaused(true)


2. 为什么你的while循环堵死了它?

当你的代码进入了while(!m_stop)这种大循环(解码循环)时,办事员的状态变成了这样:

void VideoWorker::startDecode() { // 办事员进入了这个房间,并反锁了门 while (!m_stop) { // A. 解码一帧视频 // B. 计算同步时间 // C. 渲染画面 // ... 他在这个循环里转圈圈,永远回不到上面的“检查邮件”步骤 } }

关键点在于:

  • 邮箱在门外:Qt::QueuedConnection投递的事件是放在该线程的**事件队列(邮箱)**里的。

  • 没空收信:办事员(子线程)正忙着在while循环里“解码”,只要这个while循环不结束,他就没有机会回到事件循环的processEvent()阶段去开邮箱。

  • 后果:你的暂停指令(邮件)就一直堆在邮箱里,直到while循环因为某种原因(比如播放结束)退出了,他才会去开箱,但那时候暂停已经没意义了。


3. 图解对比

状态线程行为事件处理情况
空闲/标准状态循环执行exec()正常。像前台文员,每干完一个杂活就看一眼信箱。
你的死循环状态循环执行decode()失效。像流水线工人,手一直在动,即使信箱塞满了,他也看不见。

4. 为什么“直接调用”和“原子变量”能解决?

当你把QueuedConnection改成在主线程直接调用worker->setPaused(true)时:

  1. 不走邮箱:主线程直接冲进子线程的房间,强行修改了桌子上的一个开关(std::atomic<bool> m_paused)。

  2. 瞬间生效:此时子线程虽然还在while循环里转圈,但它下一圈跑到waitIfPaused()这行代码时:

    void waitIfPaused() { if (m_paused.load()) { // 这里它读到了主线程刚改掉的开关! // 乖乖进入阻塞等待状态 } }
  3. 结果:子线程被“绊了一跤”,停在了原地。

总结

子线程不是“不执行”事件循环,而是它被你写的while循环给“绑架”了,导致它根本没有机会运行到 Qt 框架提供的那个负责处理事件的while循环里。

这也是为什么在处理密集型计算(如音视频解码、大文件读取)时,我们必须使用原子变量 (Atomic)互斥量 (Mutex)来进行跨线程的“硬控制”,而不是依赖“软绵绵”的异步信号。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/30 6:57:48

小程序计算机毕设之基于springboot+Android的研学旅行服务平台APP小程序设计研学产品展示(主题路线、课程安排、师资介绍)(完整前后端代码+说明文档+LW,调试定制等)

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

作者头像 李华
网站建设 2026/6/1 3:23:48

小程序计算机毕设之基于springboot+微信小程序的宠物服务系统小程序基于微信小程序的宠物服务系统(完整前后端代码+说明文档+LW,调试定制等)

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

作者头像 李华
网站建设 2026/5/31 11:26:07

小程序毕设项目:基于springboot+微信小程序的宠物服务系统小程序(源码+文档,讲解、调试运行,定制等)

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

作者头像 李华
网站建设 2026/6/2 4:19:28

2025 年 IT 转行选什么?网络安全为何是首选方向?

2025年IT转行就业为什么首先要选网络安全&#xff1f; 记得曾经有人说过这样一个俗语&#xff1a;三百六十行&#xff0c;行行转IT。或许听到这个话的时候会觉得是一句玩笑话&#xff0c;但是浏览到网络上一些关于就业的文章&#xff0c;就能够明白这句话的真正意义所在。随着…

作者头像 李华
网站建设 2026/6/1 7:47:17

小白必看 SQL 注入教程:详细图解 + 基础原理,核心逻辑一看就懂

一、Sql注入简介 Sql 注入攻击是通过将恶意的 Sql 查询或添加语句插入到应用的输入参数中&#xff0c;再在后台 Sql 服务器上解析执行进行的攻击&#xff0c;它目前黑客对数据库进行攻击的最常用手段之一。 二、Web 程序三层架构 三层架构(3-tier architecture) 通常意义上就…

作者头像 李华
网站建设 2026/5/31 0:10:58

【ACWing】153. 双栈排序

题目地址&#xff1a; https://www.acwing.com/problem/content/description/155/ Tom最近在研究一个有趣的排序问题。通过 2 2 2个栈S1和S2&#xff0c;Tom希望借助以下 4 4 4种操作实现将输入序列升序排序。 操作a&#xff1a;如果输入序列不为空&#xff0c;将第一个元素…

作者头像 李华