QThread多线程编程经典案例分析
传统的图形界面应用程序都只有一个线程执行,并且一次执行一个操作。如果用户调用一个比较耗时的操作,就会冻结界面响应。
一个解决方法是按照事件处理的思路:
调用 Void QApplication::processEvents() 或 void QApplication::processEvents ( int maxtime ) 来强迫事件循环进行,但是这种做法是有潜在风险的。按照QCoreApplication:processEvents()可能会引起递归,导致栈溢出崩溃的说法,当主线程在某个槽函数里正在执行processEvents时, 刚好有一个能响应此槽函数的信号发送过(肯定是其他线程发的信号), 这时就可能会发生可怕的递归, 导致栈溢出崩溃。 原因是processEvents在处理自己槽函数的事件时,又会调用到processEvents,进入到无尽的递归中。
另外一个解决方法是:采用多线程。、
QT QThread多线程编程的方法一直有个争议,就是Bradley T. Hughes:You’re doing it wrong 归纳为3中方法优劣问题:
方法(1):
1. 不使用事件循环。这是官方的 Manual 、example 以及相关书籍中都介绍的一种的方法。
a. 子类化 QThread
b. 重载 run 函数,run函数内有一个 while 或 for 的死循环
c. 设置一个标记为来控制死循环的退出。这里的run函数自己执行了一个循环,不需要事件循环机制了。
方法(2):
这种方法也是Bradley T. Hughes极力批判的 a. 子类化 QThread, b. 重载 run 使其调用 QThread::exec() c. 并为该类定义信号和槽,这样一来,由于槽函数并不会在新开的 thread 运行,很多人为了解决这个问题在构造函数中调用 moveToThread(this);
而争论和不解正是这样的一条语句造成的。
Bradley T. Hughes 给出说明是: QThread 应该被看做是操作系统线程的接口或控制点,而不应该包含需要在新线程中运行的代码。需要运行的代码应该放到一个QObject的子类中,然后将该子类的对象moveToThread到新线程中。
方法(3):
在Qt4.3(包括)之前,run 是虚函数,必须子类化QThread来实现run函数。而从Qt4.4开始,qthreads-no-longer-abstract ,run 默认调用 QThread::exec() 。这样一来不需要子类化 QThread 了,只需要子类化一个 QObject 就够了,这正是被 Bradley T. Hughes推荐的方法。方法如下
QThread thread;
Object obj;
Dummy dummy;
obj.moveToThread(&thread);
QObject::connect(&dummy, SIGNAL(sig()), &obj, SLOT(slot()));
thread.start();
所以,方法(1)和方法(3)是正确的QT QThread多线程编程方法,方法(2)用的最多,但只是三人成虎,一种不恰当的用法
QThread多线程编程经典案例分析的更多相关文章
- QThread多线程编程经典案例分析(三种方法,解释了为什么使用moveToThread的根本原因,即为了避免调用QThread::exec() )
传统的图形界面应用程序都只有一个线程执行,并且一次执行一个操作.如果用户调用一个比较耗时的操作,就会冻结界面响应. 一个解决方法是按照事件处理的思路: 调用 Void QApplication::pr ...
- 阿里云资深DBA专家罗龙九:云数据库十大经典案例分析【转载】
阿里云资深DBA专家罗龙九:云数据库十大经典案例分析 2016-07-21 06:33 本文已获阿里云授权发布,转载具体要求见文末 摘要:本文根据阿里云资深DBA专家罗龙九在首届阿里巴巴在线峰会的&l ...
- 猴子吃桃问题之《C语言经典案例分析》
猴子吃桃问题之<C语言经典案例分析>一.[什么是猴子吃桃] 猴子吃桃问题:猴子第一天摘下若干个桃子,当即吃了一半,还不过瘾,又多吃了一个.第二天早上又将第一天剩下的桃子吃掉一半 ...
- C语言项目——工程化编程的案例分析
一.VSCode安装及环境配置 初始在Win下安装Mingw-w64/GCC 和 GDB,在VSCode下打开项目案例,发现在linktable中需要包含pthread头文件.此文件是基于Linux系 ...
- Linux多线程编程之详细分析
线程?为什么有了进程还需要线程呢,他们有什么区别?使用线程有什么优势呢?还有多线程编程的一些细节问题,如线程之间怎样同步.互斥,这些东西将在本文中介绍.我见到这样一道面试题: 是否熟悉POSIX多线程 ...
- 【MySQL经典案例分析】关于数据行溢出由浅至深的探讨
本文由云+社区发表 一.从常见的报错说起 故事的开头我们先来看一个常见的sql报错信息: 相信对于这类报错大家一定遇到过很多次了,特别对于OMG这种已内容生产为主要工作核心的BG,在内容线的存 ...
- 【MySQL经典案例分析】 Waiting for table metadata lock
本文由云+社区发表 一. 问题是这样来的 2018年某个周末,接到连续数据库的告警,告警信息如下: 二. 苦逼的探索过程 1.总体的思路 看到too many connection的报错信息,基本 ...
- .Net多线程编程—误用点分析
1 共享变量问题 错误写法: 所有的任务可能会共享同一个变量,所以输出结果可能会一样. public static void Error() { ;i<;i++) { Task.Run(() = ...
- mysql经典案例分析
问题: create table A ( id varchar(64) primary key, ver int, ...)在id,ver上有联合索引,10000条数据为什么select id fro ...
随机推荐
- !"false"==fasle
首先要搞清楚优先级 !"false" --->false false == false;---->true !""--->true; !&qu ...
- 【JavaScript】 2013年度最强AngularJS资源合集
http://www.iteye.com/news/28651-AngularJS-Google-resource AngularJS是Google开源的一款JavaScript MVC框架,弥补了H ...
- 设计模式 ( 十八 ) 策略模式Strategy(对象行为型)
设计模式 ( 十八 ) 策略模式Strategy(对象行为型) 1.概述 在软件开发中也经常遇到类似的情况,实现某一个功能有多种算法或者策略,我们能够依据环境或者条件的不同选择不同的算法或者策略来完毕 ...
- Golang学习 - io/ioutil 包
------------------------------------------------------------ // Discard 是一个 io.Writer 接口,调用它的 Write ...
- V8::Arguments中This和Holder的区别
## v8::Arguments namespace v8 { class Arguments { public: inline int Length() const; inline Local& ...
- The Kernel Newbie Corner: Kernel Debugging with proc "Sequence" Files--Part 3
转载:https://www.linux.com/learn/linux-career-center/44184-the-kernel-newbie-corner-kernel-debugging-w ...
- c++ 设计模式4 (Strategy)
3.2 Strategy (策略模式) 动机:在软件构建过程中,某些对象使用的算法可能多种多样,经常改变,如果将这些算法都编码到对象中,将会使对象变得异常复杂,而且有时候支持不使用或不常使用的算法也是 ...
- Souerce 之 图片格式
一.基本概念 1.矢量图与位图 1)矢量图-完美的几何图形 矢量图是通过组成图形的一些基本元素,如点.线.面,边框,填充色等信息通过计算的方式来显示图形的.就好比我们在几何学里面描述一个圆可以通过它的 ...
- Play on Words 欧拉通路(回路)判断
Play on Words note: 判断一下连通性. #include <iostream> #include <cstdio> #include <cstring ...
- 【Mood-10】每个程序员都应该读的30本书
“如果能时光倒流,回到过去,作为一个开发人员,你可以告诉自己在职业生涯初期应该读一本,你会选择哪本书呢?我希望这个书单列表内容丰富,可以涵盖很多东西.” 很多程序员响应,他们在推荐时也写下自己的评语. ...