QT线程池实验研究与分析(QThread与和QThreadPool + QRunnable使用上的区别)

2023-11-18

第一部分:QT线程池的构建与使用

    网上关于QT线程池QThreadPool的文章很多,而且大都千篇一律,基本上都是参考QT的帮助文档介绍QT全局线程池的用法。这样就往往会使人产生误解,QT是不是推荐大家使用其全局线程池,而不推荐使用自定义构造的线程池? 实际情况并不是这样的。而且在实际的项目当中我们通常并不希望仅仅使用一个全局的线程池,而是在需要线程池的工程中都构建和维护自己一个小小的线程池(我们知道一个良好架构的项目通常是由多个工程组成的)。综上,我们来分析以下两个问题:

    (1)    非全局的线程池如果构建与使用呢?

[cpp] view plain  copy  print ? 在CODE上查看代码片 派生到我的代码片
  1. #include <QObject>  
  2. #include <QRunnable>  
  3. #include <QThread>  
  4. #include <QThreadPool>  
  5. #include <QDebug>  
  6. class HelloWorldTask : public QRunnable  
  7. {  
  8.      // 线程执行任务:每间隔1s打印出线程的信息  
  9.     void run()  
  10.     {  
  11.         for (int nCount = 0; nCount < 5; nCount++)  
  12.         {  
  13.         qDebug() << QThread::currentThread();  
  14.         QThread::msleep(1000);  
  15.         }  
  16.     }  
  17. };  
  18. int main(int argc, char *argv[])  
  19. {  
  20.     QCoreApplication a(argc, argv);  
  21.   
  22.     QThreadPool   threadpool;              // 构建一个本地的线程池  
  23.     threadpool.setMaxThreadCount(3);         // 线程池中最大的线程数  
  24.         for (int nNum = 0; nNum < 100; nNum++)  
  25.     {  
  26.         HelloWorldTask   *task;    // 循环构建可在线程池中运行的任务  
  27.         threadpool.start(task);      //线程池分配一个线程运行该任务  
  28.         QThread::msleep(1000);  
  29.     }  
  30.     return a.exec();  
  31. }  

    上述程序,构建了一个线程最大数量为3的本地线程池。每间隔1s的时间创建一个线程任务并置入到线程池的任务队列中(QT内部机制实现该队列,我们只需要调用QThreadPool的start函数置入即可)。每个线程任务的持续时间为5s。

    (2)    程序当中QRunnable是以指针的形式创建的,该指针是需要程序员去释放,还是QThreadPool在运行完线程后自动释放?

    解答:在上述例子当中,我们创建的QRunnable类型的指针 QRunnable *task 是不需要我们手动去回收内存的,QThreadPool在结束该任务的执行后会将对该内存进行清空。

    上述解答并不是凭空猜测,一方面根据是QT文档中的一句话:

    QThreadPool takes ownership and deletes 'hello'automatically

     用直白的话说就是:QThreadPool会占有这个指针的句柄并在运行结束后释放指针所占的内存。

    另一方面,我们也通过改进上面的例子进行验证。

[cpp] view plain  copy  print ? 在CODE上查看代码片 派生到我的代码片
  1. #include <QObject>  
  2. #include <QRunnable>  
  3. #include <QThread>  
  4. #include <QThreadPool>  
  5. #include <QDebug>  
  6. class HelloWorldTask : public QRunnable  
  7. {  
  8.      // 线程执行任务:每间隔1s打印出线程的信息  
  9.     void run()  
  10.     {  
  11.             int         m_dataMem[256*1000];                  // 占约 1MB内存空间   
  12.         for (int nCount = 0; nCount < 5; nCount++)  
  13.         {  
  14.         qDebug() << QThread::currentThread();  
  15.         QThread::msleep(1000);  
  16.         }  
  17.     }  
  18. };  
  19. int main(int argc, char *argv[])  
  20. {  
  21.     QCoreApplication a(argc, argv);  
  22.   
  23.     QThreadPool   threadpool;   
  24.     threadpool.setMaxThreadCount(1);   
  25.         for (int nNum = 0; nNum < 100; nNum++)  
  26.     {  
  27.         HelloWorldTask   *task;   
  28.         threadpool.start(task);   
  29.         QThread::msleep(1000);  
  30.     }  
  31.     return a.exec();  
  32. }  

     在程序运行过程中,我们观察发现程序的进程一直仅占用约1MB的内存空间。如果在main函数中所创建的100个HelloWorldTask 指针对象没有被QThreadPool释放的话,随着程序的运行该程序所占内存空间应该逐步攀升到约100MB。然而实际情况是,该程序最高仅占用1MB的内存空间。

    综上两个方面可以得出以下结论:QRunnable创建的对象QThreadPool在执行完该对象后会帮助我们来清空内存,不需要我们手动回收内存。


第二部分:QThread 与QRunnable + QThreadPool适用的应用场景

    QThread是QT的线程类,通过继承QThread然后重写run函数即可实现一个线程类。QThreadPool+ QRunnable配合构建线程池的方法也可以实现线程。我们通过以下问题对上述两种构建线程的方法进行分析和说明。

    (1)既然QThread这么简单我们为什么还要使用QThreadPool + QRunnable创建线程池的方法来使用线程机制呢?

主要原因:当线程任务量非常大的时候,如果频繁的创建和释放QThread会带来比较大的内存开销,而线程池则可以有效避免该问题,相关的基础支持可以自行百度线程池的优点。

    (2)QThread与 QThreadPool + QRunnable分别适用于哪种应用场景?

     QThread适用于那些常驻内存的任务。而且QThread可以通过信号/槽的方式与外界进行通信。而QRunnable则适用于那些不常驻内存,任务数量比较多的情况。

 

第三部分:QRunnable 如何与外界进行通信

       方法1:QRunnable并不继承自QObject类,因此无法使用信号/槽的方式与外界进行通信。我们就必须的使用其他方法,这里给大家介绍的是使用:QMetaObject::invokeMethod()函数。

       方法2:使用多重继承的方法,任务子类同时继承自QRunnable和QObject。




FROM:http://blog.csdn.net/qinpanke/article/details/51705283

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

QT线程池实验研究与分析(QThread与和QThreadPool + QRunnable使用上的区别) 的相关文章

  • Java中StringBuffer类常用方法介绍

    StringBuffer类的介绍 StringBuffer是字符串缓存区 当new的时候是在堆内存创建了一个对象 底层是一个长度为16的 字符数组当调用添加的方法时 不会再重新创建对象 在不断向原缓冲区添加字符 查看字符串缓存区容量和长度
  • 快速傅氏变换之旅(一) 概念简介 3

    1 蝶形变换 普通的FFT算法称为基2的FFT算法 这种算法的核心是蝶形变换 长度为n 2 k1的变换共需要做 k1 n 2 次蝶形变换 如上图所示 若需变换数据表示为一个复数数组c 则每次蝶形变换有2个输入 c i c i s 两个输出
  • JS解密日记

    前言 JS混淆是通过改变JS代码的语法结构来使代码难以阅读和理解的技术 然而 请注意 混淆并不能真正保护您的代码 因为它仍然可以被解密和恢复其原始形式 直接上源代码 eval function p a c k e r e function
  • C11:mutex和lock_guard的使用.

    在C 11中 引入了有关线程的一系列库 且都在std命名空间内 下面演示一个使用线程的例子 非常的简单 引入了thread和mutex头文件 include
  • 攻防世界 inget

    打开网页提示 Please enter ID and Try to bypass 输入id绕过 尝试一下万能钥匙 尝试要不要符号闭合 http 61 147 171 105 49280 id 1 or 1 1 加个单引号成功 http 61
  • 【菜鸟C++学习杂记】ASCII码转换和显示

    笔者今年刚考上华东某高校的计算机研究生 本科虽是计算机学院 但期间主攻C 和Unity游戏开发 研究生属于小跨到计算机科学与技术 目前在进行硕导给的假期期间学习C 的任务 此类杂记主要记录下编码过程遇到的一些有趣的小知识 在某网课遇到了一个
  • 运用PL/SQL从1~100(包含边界)偶数之和

    1 第一种 方式实现 代码 set serveroutput on declare number integer 0 i integer 0 begin while i lt 100 loop number number i i i 2 e
  • 巴比特

    摘要 据 科创板日报 报道 当地时间5月9日 Meta宣布开源了一种可以横跨6种不同模态的全新AI模型ImageBind 包括视觉 图像和视频形式 温度 红外图像 文本 音频 深度信息 运动读数 由惯性测量单元或IMU产生 ImageBin
  • 为什么需要进程间通信??

    进程是一个独立的资源分配单元 不同进程 这里所说的进程通常指的是用户进程 之间的资源是独立的 没有关联 不能在一个进程中直接访问另一个进程的资源 例如打开的文件描述符 但是 进程不是孤立的 不同的进程需要进行信息的交互和状态的传递等 因此需
  • 微信公众号支付H5调用支付详解

    原文地址 http blog csdn net fengshizty article details 45564685 微信公众号支付 最近项目需要微信支付 然后看了下微信公众号支付 虽然不难 但是细节还是需要注意的 用了大半天时间写了个d
  • [Java]JAVA获取实体与List 数组的转换

    public class BeanToArray private String beanNames private Object values public BeanToArray public BeanToArray String bea
  • vs添加第三方库详解

    vs添加第三方库详解 一 编写库所生成的文件 核心文件 二 两种使用库的方式 此时添加一个Pro工程调用这个库 三 库导出函数时候的细节情况 四 新建工程使用这个库 以前总是不知道怎么使用第三方库 每次想学习一个库进行开发 总是遇到各种各样
  • Java中关于System.out.println/print的运算规则

    一 输出到控制台 System out println msg 输出一个字符串 带换行 n System out print msg 输出一个字符串 不带换行 n System out printf format msg 格式化输出 注 p
  • SpringMVC的请求(参数绑定注解、Restful风格的参数的获取、自定义类型转换器、获得Servlet相关API)

    SpringMVC的请求 获得请求参数 SpringMVC的请求 获得请求参数 SpringMVC的请求 获得请求参数 1 SpringMVC的请求 获得请求参数 配置全局乱码过滤器 2 SpringMVC的请求 获得请求参数 参数绑定注解
  • Serializable简单介绍

    Serializable 序列化 什么是序列化 序列化是将对象状态转化为可保持或者传输的格式过程 与序列化相反的是反序列化 完成序列化和反序列化 可以存储或传输数据 一般情况下 在定义实体类时会使用Serializable 为什么要序列化对

随机推荐

  • 硬件学习——I2C

    I2C简单来讲就是2线的串行总线 由SDA Serial Data Line 和SCL Serial Clock Line 构成 它遵循主从结构 允许多主多从 主设备 发起 停止数据输出 并且通过控制时钟来控制数据传输过程 从设备 响应主设
  • 若依vue分离版使用字典

    首先来看官方文档 接下来我们进行操作 第一步已经添加完 来做第二步 打开index vue 在index vue中 找到变量定义的位置 一般在data 中 定义一个新数组
  • LayUI中的基本元素之面板

    前言 最近在准备找工作的事项 但是作为一个后台也是需要了解一些前端框架的 就目前的来说有大火的VUE 但是VUE还是存在一定的学习成本 所以决定先从对后台友好的LayUI开始入手先做一些小项目练练手 后面会考虑使用VUE ElementUI
  • React.Component

    React Component 本章节提供了 React class 组件的详细 API 参考 本章节默认你已熟悉基本的 React 概念 例如 组件 Props 以及 State 生命周期等 概览 React 的组件可以定义为 class
  • teacher-student network

    最近读到一篇文章 An On device Deep Neural Network for Face Detection 讲的是苹果如何将基于深度学习的人脸识别方法应用到iPhone上 同时解决多任务并行及能耗的问题 文中提到了一个teac
  • python第三方库概述_计算机二级python:python第三方库概述

    1 本节课我们进行讲解python第三方库概述 先看一下考纲考点如图所示 2 然后我们来看一下知识导图如图所示 3 查看一下pip工具安装然后进行根据要求步骤安装 4 然后我们来看一下pyinstaller库概述如图所示 5 接下来我们再来
  • android 图像识别sdk,在android系统下实现图像识别

    首先我们了解下 Android系统常用的图像识别框架 一 调用一些不开源库进行识别 旷视的图像识别及 OCR 文字识别库 及其他厂家如阿里 百度 华为 腾讯的 OCR 文字识别库等 二 调用一些开源库进行识别 一 tensorflow 训练
  • python写出梯度下降的代码

    以下是一个使用Python实现的基本梯度下降 Gradient Descent 算法的示例 导入必要的库 import numpy as np import matplotlib pyplot as plt 定义损失函数 def compu
  • seq2seq模型

    转载自 http blog csdn net sunlylorn article details 50607376
  • k--最近邻算法(KNN)

    目录 一 简介 二 举例理解 三 算法步骤 四 其他说明 1 关于距离的计算 2 超参数 3 关于K值的选择 4 取K值的方法 5 关于决策依据 6 优缺点 五 代码 一 简介 邻近算法 KNN 是数据挖掘分类技术最简单的方法之一 所谓K最
  • Asp.net_Study学习笔记

    Asp net Study web基本原理 浏览器向服务器发送请求 服务器响应 报错 HTTP Error 403 14 Forbidden Web 服务器被配置为不列出此目录的内容 解决 打开控制面板里的程序 点击启用或关闭Windows
  • Matlab实现Kmeans算法(每行代码标注详细注解)

    本文主要为了完成平日作业 并进一步加深对算法的理解 也希望对来访的读者有所帮助 该算法的优化Kmean 算法的代码详解已在其他文章给出 Matlab实现Kmeans 算法 每行代码标注详细注解 高垚淼的博客 CSDN博客 Matlab实现B
  • ESD静电放电最常用的三种模型及其防护设计

    推荐好文 建议直接看链接 1 静电放电最常用的三种模型及其防护设计 http www 360doc com content 17 0827 14 32066980 682502209 shtml 人体模型HBM 机器模型MM 充电器件模型C
  • LA@齐次线性方程组解的结构

    文章目录 齐次线性方程组解的结构 解的性质 齐次线性方程组的解的线性组合还是方程组的解 基础解系 通解 定理 齐次线性方程组基础解系存在定理 齐次线性方程组的基础解系包含的向量个数 秩 应用和示例 推论1 推论2 推论3 转置矩阵对的乘积秩
  • 解决jar文件不显示图标问题

    版权声明 本文为转载文章 遵循 CC 4 0 BY SA 版权协议 本文链接 https blog csdn net qyfx123456 article details 104713149 一 问题的产生 最近 重新装了JDK 配置了环境
  • 生命在于学习——Socket编程(偏安全方面)

    本篇文章仅用于学习记录和交流 不得用于其他违规用途 产生的不良后果 自己负责 一 Socket介绍 首先socket 套接字 是工作在应用层和传输层之间一个抽像层 为什么要有他呢 虽然我们已经有了ip port可以和世界上任意一台计算机上的
  • 扫雷游戏是一款十分经典的单机小游戏。 问题 H: 扫雷游戏

    题目描述 扫雷游戏是一款十分经典的单机小游戏 在n行m列的雷区中有一些格子含有地雷 称之为地雷格 其他格子不含地雷 称之为非地雷格 玩家翻开一个非地雷格时 该格将会出现一个数字 提示周围格子中有多少个是地雷格 游戏的目标是在不翻出任何地雷格
  • axios封装(例如:请求头、token、超时、BaseUrl、请求错误、请求重复)

    axios封装 文章目录 axios封装 前言 1 为什么封装Axios 2 包括的功能 一 Axios是什么 二 安装 Axios 1 安装axios JavaScript版本 2 安装axios TypeScript版本 三 封装 Ax
  • 关于 forza horizon 4 极限竞速地平线4 进游戏没声音 看见车没声音问题 的解决方案 (可能是微星的锅)

    这个问题可能是我微星笔记本的问题 型号GS63 7RE 018n 这个机器有个独立声卡 有个单独的sb软件 地平线4用蓝牙音箱的特殊问题 如果音箱有麦克风 声音就崩了 我用的bose soundlink 我用线从电脑上接出来 结果进了游戏就
  • QT线程池实验研究与分析(QThread与和QThreadPool + QRunnable使用上的区别)

    第一部分 QT线程池的构建与使用 网上关于QT线程池QThreadPool的文章很多 而且大都千篇一律 基本上都是参考QT的帮助文档介绍QT全局线程池的用法 这样就往往会使人产生误解 QT是不是推荐大家使用其全局线程池 而不推荐使用自定义构