Qt 中的线程池QRunnable和QThreadPool

Qt 中的线程池QRunnable和QThreadPool

一、QThreadPool类介绍

QThreadPool 是 Qt 框架中用于管理线程池的类,它提供了一种高效的方式来管理和复用线程,避免频繁创建和销毁线程带来的开销。

1. 基本概念

QThreadPool 是一个全局的线程池,它维护了一组线程,并将任务分配给这些线程执行。线程池中的线程数量可以通过设置最大线程数来控制。当线程池中的线程被占用时,新任务会被排队等待执行。

2. 创建和使用线程池

Qt 提供了一个全局线程池 QThreadPool::globalInstance(),可以直接使用,也可以创建自己的线程池实例。

全局线程池的使用:

// 获取全局线程池
QThreadPool *threadPool = QThreadPool::globalInstance();
// 设置最大线程数(可选)
threadPool->setMaxThreadCount(4);

自定义线程池的使用:

QThreadPool *myThreadPool = new QThreadPool();
myThreadPool->setMaxThreadCount(8); // 设置最大线程数

3. 关键方法

以下是 QThreadPool 的一些常用方法:

(1) 设置线程池的最大线程数
void QThreadPool::setMaxThreadCount(int maxThreadCount);

用于设置线程池中允许的最大线程数。默认值通常是系统核心数的两倍。

(2) 启动任务
void QThreadPool::start(QRunnable *runnable);

将一个 QRunnable 对象提交到线程池中执行。

(3) 等待所有任务完成
void QThreadPool::waitForDone();

阻塞当前线程,直到线程池中的所有任务都完成。

(4) 获取全局线程池
static QThreadPool *QThreadPool::globalInstance();

返回全局线程池实例,通常用于共享程线池。

4. 注意事项

  1. 线程安全QThreadPool 是线程安全的,可以在多个线程中同时调用其方法。
  2. 任务的生命周期:任务对象(QRunnable 的子类)通常由线程池管理,任务完成后会被自动删除。如果需要手动管理任务对象的生命周期,可以在任务类中重写 autoDelete() 方法。
  3. 任务队列:当线程池中的线程被占用时,新任务会被放入队列中等待执行。
  4. 线程池的销毁:当线程池被销毁时,所有未完成的任务会被取消,线程池中的线程也会被销毁。

二、QRunnable类介绍

QRunnable 是 Qt 框架中用于表示可运行任务的类,它是线程池(QThreadPool)中任务的接口。通过继承 QRunnable 并重写其 run() 方法,可以创建一个可以在单独线程中执行的任务。QRunnable 是 Qt 实现线程池任务调度的核心机制之一。

1. QRunnable 的作用

QRunnable 是一个抽象类,用于表示一个可以被线程执行的任务。它的主要目的是将任务封装为一个对象,然后通过线程池(QThreadPool)或其他线程管理机制来执行这些任务。QRunnable 的设计使得任务的创建和执行解耦,从而提高了代码的可维护性和可扩展性。

2. QRunnable 的基本用法

要使用 QRunnable,通常需要执行以下步骤:

1继承 QRunnable:创建一个继承自 QRunnable 的类。

2.重写 run() 方法:在 run() 方法中实现任务的逻辑。

3.提交任务到线程池:通过 QThreadPoolstart() 方法将任务提交到线程池中执行。

3. QRunnable 的关键特性

(1) 自动删除

QRunnable 提供了一个 autoDelete() 方法,用于控制任务对象在执行完成后是否自动删除。默认情况下,autoDelete() 返回 true,表示任务对象会在执行完成后自动删除。如果需要手动管理任务对象的生命周期,可以在任务类中重写 autoDelete() 方法。

bool QRunnable::autoDelete() const;
(2) 设置优先级

QRunnable 允许设置任务的优先级,优先级高的任务会优先执行。

void QRunnable::setAutoDelete(bool autoDelete);
void QRunnable::setPriority(QThread::Priority priority);
(3) 线程安全

QRunnable 是线程安全的,可以在多个线程中同时创建和提交任务。

4. QRunnable 的应用场景

QRunnable 适用于以下场景:

1.并发任务:需要在多个线程中并发执行任务时,QRunnable 是一个很好的选择。

2.线程池管理:通过 QThreadPoolQRunnable,可以高效地管理线程池中的任务,避免频繁创建和销毁线程。

3.简化线程管理QRunnable 将任务封装为对象,使得任务的创建和执行更加清晰和易于管理。

5. QRunnable 和 QThread 的区别

虽然 QRunnableQThread 都可以用于多线程编程,但它们的用途和设计目标有所不同:

  • QThread
    • 是一个完整的线程类,提供了对线程生命周期的精细控制。
    • 适用于需要长期运行的线程,或者需要手动管理线程生命周期的场景。
    • 使用起来相对复杂,需要手动启动和停止线程。
  • QRunnable
    • 是一个任务类,用于表示一个可以在单独线程中执行的任务。
    • 通常与 QThreadPool 配合使用,适用于短时间任务的并发执行。
    • 使用起来相对简单,任务完成后会自动删除。

三、使用示例

下面通过一个代码示例来讲述如何使用:

#include <QCoreApplication>
#include <QThreadPool>
#include <QRunnable>
#include <QThread>
#include <QDebug>

class QMyTask:public QRunnable
{
public:
    QMyTask(int nID)
    {
        m_nID = nID;
    }

    ~QMyTask(){};

    virtual void run() override
    {
        qDebug() << "Task"<< m_nID << "Is Run On Thread" << QThread::currentThreadId();
        QThread::sleep(2); // 模拟耗时任务
        qDebug() << "Task" << m_nID << "finished";
    }

private:
    int m_nID;
};


int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    
    QThreadPool* pThreadPool = QThreadPool::globalInstance();
    pThreadPool->setMaxThreadCount(4);

    for(int i=0;i<10;i++)
    {
        QMyTask* pTask = new QMyTask(i);
        pThreadPool->start(pTask);
    }

    pThreadPool->waitForDone();

    qDebug() << "All tasks are done.";


    return a.exec();
}

代码运行结果:

微信截图_20250223112303

四、总结

1.QThreadPool 提供了一种简单而高效的方式来管理线程,特别适合处理大量短时间任务的场景。通过合理设置线程池的大小和任务的管理方式,可以显著提高程序的性能和响应速度。

2.QRunnable 是 Qt 中用于表示可运行任务的类,它通过线程池(QThreadPool)实现任务的并发执行。通过继承 QRunnable 并重写 run() 方法,可以轻松创建和管理任务。QRunnable 的设计使得任务的创建和执行解耦,提高了代码的可维护性和可扩展性。在需要并发执行短时间任务时,QRunnable 是一个非常高效的选择。

参考文章:

1.QT线程池的使用:QThreadPool类和QRunnable类

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/975508.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

C++中结构体与结构体变量 和 类与对象的区别

具体区别如下&#xff1a; 结构体 -> 结构体变量 { 结构体&#xff1a;struct student{ 具体是多少&#xff0c;年龄&#xff0c;名字&#xff0c;性别&#xff0c;成绩 } 结构体变量&#xff1a; stu{ 名字&#xff1a;张三&#xff0c;年龄&#xff1a;18&#…

一周学会Flask3 Python Web开发-flask3模块化blueprint配置

锋哥原创的Flask3 Python Web开发 Flask3视频教程&#xff1a; 2025版 Flask3 Python web开发 视频教程(无废话版) 玩命更新中~_哔哩哔哩_bilibili 我们在项目开发的时候&#xff0c;多多少少会划分几个或者几十个业务模块&#xff0c;如果把这些模块的视图方法都写在app.py…

11套免费web登录页面模板分享

1.纯色 2.纯色 3.纯色 4.联系我们 5.纯色 6.动画 7.现代 8.现代 9.单调 10.现代 11.简约

Fences 5深度解析:一键打造超高效整洁桌面

在信息爆炸的时代,电脑桌面往往成为各种文件、图标和快捷方式的“聚集地”。杂乱无章的桌面不仅影响视觉体验,还可能降低工作效率。而Fences 5,这款由Stardock公司精心打造的桌面管理工具,凭借其强大的功能和便捷的操作,成为了众多用户整理桌面的得力助手。本文将带大家深…

一篇docker从入门到精通

Docker Docker 是一个开源的应用容器引擎&#xff0c;让开发者可以打包他们的应用以及依赖包到一个可移植的容器中&#xff0c;然后发布到任何流行的 Linux 机器上&#xff0c;也可以实现虚拟化。容器是完全使用沙盒机制&#xff0c;相互之间不会有任何接口&#xff08;类似 iP…

【深度学习】Unet的基础介绍

U-Net是一种用于图像分割的深度学习模型&#xff0c;特别适合医学影像和其他需要分割细节的任务。如图&#xff1a; Unet论文原文 为什么叫U-Net&#xff1f; U-Net的结构像字母“U”&#xff0c;所以得名。它的结构由两个主要部分组成&#xff1a; 下采样&#xff08;编码…

医疗AI领域中GPU集群训练的关键技术与实践经验探究(上)

医疗AI领域中GPU集群训练的关键技术与实践经验探究(上) 一、引言 1.1 研究背景与意义 在科技飞速发展的当下,医疗 AI 作为人工智能技术与医疗领域深度融合的产物,正引领着医疗行业的深刻变革。近年来,医疗 AI 在疾病诊断、药物研发、健康管理等诸多方面取得了显著进展,…

使用matplotlib绘制柱状图并在下面使用表格显示数值

使用matplotlib绘制柱状图并在下面使用表格显示数值 1、效果 2、流程 1、数据准备 2. 创建可视化布局 3.、绘制柱状图 4、创建表格 5、设置字体大小、标题、图例 6、显示图表3、代码 import matplotlib.pyplot as plt from matplotlib.gridspec import GridSpec import nump…

Windows11安装GPU版本Pytorch2.6教程

1: 准备工作 针对已经安装好的Windows11系统&#xff0c;先检查Nvidia驱动和使用的CUDA版本情况。先打开Windows PowerShell&#xff0c;通过nvidia-smi命令查看GPU的情况&#xff0c;结果如下图1所示&#xff0c;从结果中可知使用的CUDA版本为12.8。 图1&#xff1a;检测安装…

《Spring实战》(第6版) 第3章 使用数据

第3章 使用数据 使用Spring的JdbcTemplate&#xff1b;创建Spring Data JDBC存储库&#xff1b;使用Spring Data声明JPA存储库&#xff1b; 本章对Taco Cloud应用添加对数据库持久化的支持&#xff0c;关注JDBC和JPA。 3.1 使用JDBC读取和写入数据 Spring对JDBC的支持要归功…

设计模式 - Singleton pattern 单例模式

文章目录 定义单例模式的实现构成构成UML图 单例模式的六种实现懒汉式-线程不安全懒汉式-线程安全饿汉式-线程安全双重校验锁-线程安全静态内部类实现枚举实现 总结其他设计模式文章&#xff1a;最后 定义 单例模式是一种创建型设计模式&#xff0c;它用来保证一个类只有一个实…

出行项目案例

spark和kafka主要通过Scala实现&#xff0c;Hadoop和HBase主要基于java实现。 通过该项目&#xff0c;主要达到以下目的&#xff1a; &#xff08;1&#xff09;通用的数据处理流程&#xff0c;入门大数据领域 &#xff08;2&#xff09;真实体验大数据开发工程师的工作 &a…

从零开始制作一个漂亮的悬浮按钮

0.1血版 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</title> </head> &l…

安全面试2

文章目录 简单描述一下什么是水平越权&#xff0c;什么是垂直越权&#xff0c;我要发现这两类漏洞&#xff0c;那我代码审计要注意什么地方水平越权&#xff1a;垂直越权&#xff1a;水平越权漏洞的审计重点垂直越权漏洞的审计重点 解释一下ssrf漏洞原理攻击场景修复方法 横向移…

数字电子技术基础(二十一)——双极型三极管的开关特性

目录 1 半导体三极管的开关特性 1.1 双极性三极管的开关特性 1.2 双极型三极管的基本开关电路 1.3 三极管的开关等效电路 1.4 双极型三极管的动态开关特性 TTL门电路是一种基于双极型晶体管的数字逻辑电路&#xff0c;在20世纪60年代到80年代之间&#xff0c;TTL门电路是应…

足疗店会员管理系统,足疗养生全方位会员管理解决方案,佳易王试用版养生会所足疗店推拿按摩会员管理系统操作教程

一、概述 本实例以佳易王试用版养生会所足疗店推拿按摩会员管理系统17.1版本为例说明&#xff0c;其他版本可参考本实例。试用版软件资源可到文章最后了解&#xff0c;下载的文件为压缩包文件&#xff0c;请使用免费版的解压工具解压即可试用。 软件特点&#xff1a; 1、功能…

【HarmonyOS Next】拒绝权限二次申请授权处理

【HarmonyOS Next】拒绝权限二次申请授权处理 一、问题背景&#xff1a; 在鸿蒙系统中&#xff0c;对于用户权限的申请&#xff0c;会有三种用户选择方式&#xff1a; 1.单次使用允许 2.使用应用期间&#xff08;长时&#xff09;允许 3.不允许 当用户选择不允许后&#xff0…

论文笔记(七十二)Reward Centering(四)

Reward Centering&#xff08;四&#xff09; 文章概括摘要附录A 伪代码 文章概括 引用&#xff1a; article{naik2024reward,title{Reward Centering},author{Naik, Abhishek and Wan, Yi and Tomar, Manan and Sutton, Richard S},journal{arXiv preprint arXiv:2405.09999…

数据结构之二叉树的定义及实现

1. 树的概念 主要的定义&#xff1a; 节点的度&#xff1a;一个节点含有的子树的个数称为该节点的度&#xff1b;如上图&#xff1a;A的为6 叶节点或终端节点&#xff1a;度为0的节点称为叶节点&#xff1b;如上图&#xff1a;B&#xff0c;C&#xff0c;H&#xff0c;I等节点…

Deepseek 与 ChatGPT:AI 浪潮中的双子星较量

引言 在人工智能飞速发展的当下&#xff0c;AI 语言模型成为了人们关注的焦点。Deepseek 与 ChatGPT 作为其中的佼佼者&#xff0c;各自展现出独特的魅力&#xff0c;引领着 AI 技术的发展潮流。今天&#xff0c;就让我们深入探讨这两款模型&#xff0c;看看它们在 AI 领域中是…