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 ...
随机推荐
- Maven实战之Quick Start
Introduction Maven是一个异常强大的构建工具,能够帮我们自动化构建过程,从清理.编译.测试到生成报告,再到打包和部署.通过Maven,我们只需要输入简单的命令(如mvn clean i ...
- [Angular2 Form] Understand the Angular 2 States of Inputs: Pristine and Untouched
Angular 2’s ngModel exposes more than just validity, it even gives you the states of whether the inp ...
- 大一C语言结课设计之《学生信息管理系统》
第一次写这么长的程序,代码仅供參考,有问题请留言. /* ** 学生信息管理系统 ** IDE:Dev-Cpp 4.9.9.2 ** 2014-6-15 */ #include <stdio.h ...
- mysql 历史记录查询
SHOW SLAVE STATUS insert into jy510_admin set userid='123123' mysqlbinlog d:xampp\mysql\data\mysql-b ...
- 非常详细的 Docker 学习笔记
一.Docker 简介 Docker 两个主要部件: Docker: 开源的容器虚拟化平台 Docker Hub: 用于分享.管理 Docker 容器的 Docker SaaS 平台 -- Docke ...
- C++字符串处理封装类String
概述 C++在处理字符串时相对于python等脚本语言并没有什么优势,下面将常用的字符串处理函数封装成一个String工具类,方便以后使用,后期还会对该类进行扩充,下面是具体的实现: // Strin ...
- hive和hbase整合的原因和原理
为什么要进行hive和hbase的整合? hive是高延迟.结构化和面向分析的: hbase是低延迟.非结构化和面向编程的. Hive集成Hbase就是为了使用hbase的一些特性.或者说是中和它们的 ...
- IOS 从系统图库中获取 图片 并设置为头像
总会遇到一些应用 要拍照 设置图片之类的的 总结一个方法备用 以后 会 继续拓展到 多图 @interface AddCustomerViewController : UIViewControll ...
- [WinForm] TableLayoutPanel和FlowLayoutPanel的使用
这篇文章主要跟大家分享下,在配餐系统的开发中,对tableLayoutPanel 和 flowLayoutPanel 控件的使用方法和技巧 ——后附上 测试demo, 相信需要的朋友下载看后能很快的知 ...
- jQery无缝滚动效果
思路: 赋值所有li,添加到ul末尾,重新计算ul宽度 每次移动一个固定的值,当超出一半时,将ul拉回原位 以下代码 <!DOCTYPE html> <html> <he ...