Qt中的线程池
Qt中的线程池
目录
1 为什么需要线程池
2 Qt中有哪些方式实现线程池
3 如何通过QThreadPool类实现线程池
4 如何通过QtConcurrent库实现线程池
5 如何通过自定义的方式实现线程池
5 小结
1 为什么需要线程池
创建和销毁线程是有开销的,过多地创建线程可能会导致系统资源的浪费。通过使用线程池,可以预先创建一定数量的线程,并重复使用它们来执行任务,避免频繁创建和销毁线程,从而减少了资源开销。
当有大量的任务需要执行时,线程池可以自动调度和分配任务给空闲的线程,实现并行执行,从而加快任务的处理速度。通过合理设置线程池的大小,可以充分利用系统资源,提高程序的响应性和吞吐量。
通过限制线程池的最大线程数,可以控制并发执行的任务数量,避免资源竞争和过度消耗系统资源。
线程池隐藏了线程的创建和管理细节,开发人员只需关注任务的实现,通过将任务提交给线程池,线程池会自动处理线程的创建、任务的调度和执行,减少了编程的复杂性。
线程池可以限制同时执行的线程数量,避免过多的线程导致系统资源不足或崩溃。此外,线程池还可以处理异常情况,例如线程崩溃或异常退出时,线程池可以自动重新创建新的线程,保持系统的稳定运行。
2 Qt中有哪些方式实现线程池
2、Qt提供的QtConcurrent并行编程框架库,可以简化多线程编程,实现线程池。
3、可以通过自己实现继承自QObject的线程池类,来实现更高级的线程池功能。
3 如何通过QThreadPool类实现线程池
1、创建一个继承自QRunnable的任务类,重写其run()函数,在其中实现任务的逻辑。
class MyTask : public QRunnable {
public:void run() {// 执行任务的逻辑}
};
2、使用setMaxThreadCount()函数来设置线程池的最大线程数,控制并发执行的线程数量。
QThreadPool::globalInstance()->setMaxThreadCount(5);
3、使用QThreadPool的globalInstance()静态函数来获取全局的线程池实例,并将任务对象添加到线程池中。
QThreadPool::globalInstance()->start(new MyTask());
4、调用waitForDone()函数,等待线程池中的任务执行完成。
QThreadPool::globalInstance()->waitForDone();
使用QThreadPool实现线程池功能时,QThreadPool会自动管理线程的创建、销毁和任务的调度,只需要关注任务的实现和提交,无需手动处理线程的创建和管理细节;通过合理设置线程池的最大线程数,可以控制并发执行的线程数量,从而优化性能和资源利用。
需要注意的是,QThreadPool默认使用自动删除的方式来管理任务对象的内存(即任务执行完成后会自动删除任务对象)。如果需要手动管理任务对象的内存,可以通过调用setAutoDelete(false)来禁用自动删除,并在任务执行完成后手动删除任务对象。
QThreadPool还提供了其他一些函数和信号,用于查询线程池的状态、取消任务、暂停和恢复线程池等操作;可以根据具体需求使用这些功能来实现更复杂的线程池逻辑。
4 如何通过QtConcurrent库实现线程池
1、创建一个函数或Lambda表达式,用于执行任务的逻辑。该函数或Lambda表达式的参数和返回值类型根据任务的需求而定。
void myTask(int param) {// 执行任务的逻辑
}
2、使用QThreadPool的globalInstance()函数获取全局的线程池实例,并使用setMaxThreadCount()函数来设置线程池的最大线程数。
QThreadPool::globalInstance()->setMaxThreadCount(5);
3、使用QtConcurrent::run()函数将任务提交给线程池执行。该函数会自动创建线程池,并将任务添加到线程池中;可以通过指定函数或Lambda表达式和参数来提交任务。
QtConcurrent::run(myTask, 42);
4、使用QThreadPool的waitForDone()函数来等待所有任务完成。
QThreadPool::globalInstance()->waitForDone();
QtConcurrent库还提供了其他一些函数和类,用于执行更复杂的并行任务,例如map、filter、reduce等操作。这些函数和类可以进一步简化并行任务的编写和管理。可以根据具体需求选择合适的函数和类来实现线程池的功能。
5 如何通过自定义的方式实现线程池
1、创建一个继承自QThread的线程类,该类将作为线程池中的线程。
class WorkerThread : public QThread {
public:void run() {while (true) {// 等待任务的到来QMutexLocker locker(&mutex);condition.wait(&mutex);// 执行任务的逻辑if (!tasks.isEmpty()) {QRunnable* task = tasks.dequeue();locker.unlock();task->run();delete task;}}}void addTask(QRunnable* task) {QMutexLocker locker(&mutex);tasks.enqueue(task);condition.wakeOne();}private:QMutex mutex;QWaitCondition condition;QQueue<QRunnable*> tasks;
};
2、创建一个包含线程池的容器和一些管理方法的自定义的线程池类,用于管理线程池中的线程和任务。
class MyThreadPool {
public:MyThreadPool(int threadCount) {for (int i = 0; i < threadCount; ++i) {WorkerThread* thread = new WorkerThread();thread->start();threads.append(thread);}}~MyThreadPool() {for (WorkerThread* thread : threads) {thread->quit();thread->wait();delete thread;}}void addTask(QRunnable* task) {int index = nextThreadIndex.fetchAndAddRelaxed(1) % threads.size();threads[index]->addTask(task);}private:QVector<WorkerThread*> threads;QAtomicInt nextThreadIndex = 0;
};
3、在需要使用线程池的地方,创建线程池对象,并将任务提交给线程池执行。
MyThreadPool threadPool(5);
threadPool.addTask(new MyTask());
自定义线程池类可以根据实际需求进行扩展,例如添加线程的动态增减、任务优先级的管理等功能。需要注意的是,在自定义线程池中,需要手动管理线程的创建、销毁和任务的调度,开发人员需要自行处理线程安全和任务队列的管理,确保线程池的正确运行。
自定义线程池的好处是可以更灵活地控制线程池的行为,并根据实际需求进行定制化的扩展。但同时也需要开发人员自行处理线程池的细节,包括线程的创建、销毁和任务的调度,相对来说会更复杂一些。因此,在选择实现方式时需要根据实际需求和复杂度进行权衡。
6 小结
相关文章:
Qt中的线程池
Qt中的线程池 目录 1 为什么需要线程池 2 Qt中有哪些方式实现线程池 3 如何通过QThreadPool类实现线程池 4 如何通过QtConcurrent库实现线程池 5 如何通过自定义的方式实现线程池 5 小结 1 为什么需要线程池 线程池是多线程编程中常用的一种技术,可以帮助管理系统中…...
使用Spring Boot集成中间件:Elasticsearch基础->提高篇
使用Spring Boot集成中间件:Elasticsearch基础->提高篇 导言 Elasticsearch是一个开源的分布式搜索和分析引擎,广泛用于构建实时的搜索和分析应用。在本篇博客中,我们将深入讲解如何使用Spring Boot集成Elasticsearch,实现数…...
【Docker】Dockerfile构建最小镜像
🥳🥳Welcome 的Huihuis Code World ! !🥳🥳 接下来看看由辉辉所写的关于Docker的相关操作吧 目录 🥳🥳Welcome 的Huihuis Code World ! !🥳🥳 前言 一.Dockerfile是什么 二.Dock…...
【严重】GitLab 以其他用户身份执行 Slack 命令
漏洞描述 GitLab 是由GitLab公司开发的、基于Git的集成软件开发平台。使用 Slack 命令在 Slack 聊天环境中运行常见的 GitLab 操作。 GitLab 受影响版本中,由于配置Slack/Mattermost 集成时,未正确验证用户身份信息,导致攻击者可以使用其他…...
【卡梅德生物】纳米抗体文库构建
纳米抗体文库构建服务是一项提供定制化纳米抗体文库的服务,旨在满足研究者和生物制药公司对高质量抗体的需求。这项服务通常包括以下主要步骤: 1.抗原设计和制备: -客户提供目标抗原信息,或由服务提供商协助设计抗原。 -抗原制…...
MySQL修炼手册6:子查询入门:在查询中嵌套查询
目录 写在开头1 子查询基础概念1.1 了解子查询的基本概念1.2 子查询与主查询的关系 2 标量子查询详细展开2.1 学会使用标量子查询2.1.1 在SELECT语句中使用2.1.2 在WHERE子句中使用2.1.3 在ORDER BY子句中使用 2.2 标量子查询在条件判断中的应用2.2.1 使用比较运算符2.2.2 使用…...
01章【JAVA开发入门】
计算机基本概念 计算机组成原理 计算机组装 计算机:电子计算机,俗称电脑。是一种能够按照程序运行,自动、高速处理海量数据的现代化智能电子设备。由硬件和软件所组成,没有安装任何软件的计算机称为裸机。常见的形式有台式计算机、…...
ARM day1
一、概念 ARM可以工作的七种模式用户、系统、快中断、中断、管理、终止、未定义ARM核的寄存器个数 37个32位长的寄存器,当前处理器的模式决定着哪组寄存器可操作,且任何模式都可以存取: PC(program counter程序计数器) CPSR(current program…...
ImageNet Classification with Deep Convolutional 论文笔记
✅作者简介:人工智能专业本科在读,喜欢计算机与编程,写博客记录自己的学习历程。 🍎个人主页:小嗷犬的个人主页 🍊个人网站:小嗷犬的技术小站 🥭个人信条:为天地立心&…...
Spring Boot中加@Async和不加@Async有什么区别?设置核心线程数、设置最大线程数、设置队列容量是什么意思?直接在yml中配置线程池
在 Spring 中,Async 注解用于将方法标记为异步执行的方法。当使用 Async 注解时,该方法将在单独的线程中执行,而不会阻塞当前线程。这使得方法可以在后台执行,而不会影响主线程的执行。 在您提供的代码示例中,a1() 和…...
自动化理论基础(2)—开发语言之Python
一、知识汇总 掌握 Python 编程语言需要具备一定的基础知识和技能,特别是对于从事自动化测试等领域的工程师。以下是掌握 Python 的一些关键方面: 基本语法: 理解 Python 的基本语法,包括变量、数据类型、运算符、条件语句、循环…...
Spark算子(RDD)超细致讲解
SPARK算子(RDD)超细致讲解 map,flatmap,sortBykey, reduceBykey,groupBykey,Mapvalues,filter,distinct,sortBy,groupBy共10个转换算子 (一)转换算子 1、map from pyspark import SparkContext# 创建SparkContext对象 sc Spark…...
转盘寿司(100%用例)C卷 (JavaPythonC++Node.jsC语言)
寿司店周年庆,正在举办优惠活动回馈新老客户。 寿司转盘上总共有n盘寿司,prices[i]是第i盘寿司的价格,如果客户选择了第i盘寿司,寿司店免费赠送客户距离,第i盘寿司最近的下一盘寿司i,前提是prices[j]< prices[i],如果没有满足条件的j,则不赠送寿司。 每个价格的寿司都…...
【python】搭配Miniconda使用VSCode
现在的spyder总是运行出错,启动不了,尝试使用VSCode。 一、在VSCode中使用Miniconda管理的Python环境,可以按照以下步骤进行: a. 确保Miniconda环境已经安装并且正确配置。 b. 打开VSCode,安装Python扩展。 打开VS…...
从购买服务器到部署前端VUE项目
购买 选择阿里云服务器,地址:https://ecs.console.aliyun.com/home。学生会送一个300的满减券,我买了一个400多一年的,用券之后100多点。 使用SSH连接服务器 我选择的是vscode 中SSH工具。 安装一个插件 找到配置文件配置一下…...
python中print函数的用法
在 Python 中,print() 函数是用于输出信息到控制台的内置函数。它可以将文本、变量、表达式等内容打印出来,方便程序员进行调试和查看结果。print() 函数的基本语法如下: ``` print(*objects, sep= , end=\n, file=sys.stdout, flush=False) ``` 其中,objects 是要打印…...
SpringBoot整合MyBatis项目进行CRUD操作项目示例
文章目录 SpringBoot整合MyBatis项目进行CRUD操作项目示例1.1.需求分析1.2.创建工程1.3.pom.xml1.4.application.properties1.5.启动类 2.添加用户2.1.数据表设计2.2.pojo2.3.mapper2.4.service2.5.junit2.6.controller2.7.thymeleaf2.8.测试 3.查询用户3.1.mapper3.2.service3…...
Android Studio下载gradle反复失败
我的版本:gradle-5.1.1 首先检查设置路径是否正确,参考我的修改! 解决方案 1.手动下载Gradle.bin Gradle Distributions 下载地址 注意根据编译器提示下载,我这要求下载的是bin 而不是all 2.把下载好的整个压缩包放在C:\Users\…...
【HTML5】 canvas 绘制图形
文章目录 一、基本用法二、用法详见2.0、方法属性2.1、绘制线条2.2、绘制矩形2.3、绘制圆形2.4、绘制文本2.5、填充图像 一、基本用法 canvas 标签:可用于在网页上绘制图形(使用 JavaScript 在网页上绘制图像)画布是一个矩形区域,…...
【数据结构】二叉树-堆(top-k问题,堆排序,时间复杂度)
🌈个人主页:秦jh__https://blog.csdn.net/qinjh_?spm1010.2135.3001.5343🔥 系列专栏:《数据结构》https://blog.csdn.net/qinjh_/category_12536791.html?spm1001.2014.3001.5482 目录 堆排序 第一种 编辑 第二种 …...
大数据学习栈记——Neo4j的安装与使用
本文介绍图数据库Neofj的安装与使用,操作系统:Ubuntu24.04,Neofj版本:2025.04.0。 Apt安装 Neofj可以进行官网安装:Neo4j Deployment Center - Graph Database & Analytics 我这里安装是添加软件源的方法 最新版…...
线程同步:确保多线程程序的安全与高效!
全文目录: 开篇语前序前言第一部分:线程同步的概念与问题1.1 线程同步的概念1.2 线程同步的问题1.3 线程同步的解决方案 第二部分:synchronized关键字的使用2.1 使用 synchronized修饰方法2.2 使用 synchronized修饰代码块 第三部分ÿ…...
【C++从零实现Json-Rpc框架】第六弹 —— 服务端模块划分
一、项目背景回顾 前五弹完成了Json-Rpc协议解析、请求处理、客户端调用等基础模块搭建。 本弹重点聚焦于服务端的模块划分与架构设计,提升代码结构的可维护性与扩展性。 二、服务端模块设计目标 高内聚低耦合:各模块职责清晰,便于独立开发…...
安宝特方案丨船舶智造的“AR+AI+作业标准化管理解决方案”(装配)
船舶制造装配管理现状:装配工作依赖人工经验,装配工人凭借长期实践积累的操作技巧完成零部件组装。企业通常制定了装配作业指导书,但在实际执行中,工人对指导书的理解和遵循程度参差不齐。 船舶装配过程中的挑战与需求 挑战 (1…...
C++课设:简易日历程序(支持传统节假日 + 二十四节气 + 个人纪念日管理)
名人说:路漫漫其修远兮,吾将上下而求索。—— 屈原《离骚》 创作者:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 专栏介绍:《编程项目实战》 目录 一、为什么要开发一个日历程序?1. 深入理解时间算法2. 练习面向对象设计3. 学习数据结构应用二、核心算法深度解析…...
接口自动化测试:HttpRunner基础
相关文档 HttpRunner V3.x中文文档 HttpRunner 用户指南 使用HttpRunner 3.x实现接口自动化测试 HttpRunner介绍 HttpRunner 是一个开源的 API 测试工具,支持 HTTP(S)/HTTP2/WebSocket/RPC 等网络协议,涵盖接口测试、性能测试、数字体验监测等测试类型…...
【Linux系统】Linux环境变量:系统配置的隐形指挥官
。# Linux系列 文章目录 前言一、环境变量的概念二、常见的环境变量三、环境变量特点及其相关指令3.1 环境变量的全局性3.2、环境变量的生命周期 四、环境变量的组织方式五、C语言对环境变量的操作5.1 设置环境变量:setenv5.2 删除环境变量:unsetenv5.3 遍历所有环境…...
django blank 与 null的区别
1.blank blank控制表单验证时是否允许字段为空 2.null null控制数据库层面是否为空 但是,要注意以下几点: Django的表单验证与null无关:null参数控制的是数据库层面字段是否可以为NULL,而blank参数控制的是Django表单验证时字…...
AD学习(3)
1 PCB封装元素组成及简单的PCB封装创建 封装的组成部分: (1)PCB焊盘:表层的铜 ,top层的铜 (2)管脚序号:用来关联原理图中的管脚的序号,原理图的序号需要和PCB封装一一…...
轻量安全的密码管理工具Vaultwarden
一、Vaultwarden概述 Vaultwarden主要作用是提供一个自托管的密码管理器服务。它是Bitwarden密码管理器的第三方轻量版,由国外开发者在Bitwarden的基础上,采用Rust语言重写而成。 (一)Vaultwarden镜像的作用及特点 轻量级与高性…...
