QT异步编程之线程池QThreadPool

一、概述

         在一个应用程序中,我们需要多次使用线程,也就意味着,我们需要多次创建并销毁线程。而创建线程并销毁线程的过程势必会消耗内存。QThreadPool是Qt框架中用于管理线程池的类。它提供了一种高效的方式来管理和重用线程,从而减少线程创建和线程的开销。

二、QThreadPool的核心功能

1、线程重用:QThreadPool维护一组线程,任务完成后线程不会被销毁,而是保留在线程池中等待下一个任务。

2、任务队列:当所有线程都在忙碌时,新任务会被放入队列中,等待线程空闲处理。

3、自动扩展和收缩:根据任务数量动态调整线程池中的线程数量。

4、全局线程池:Qt提供了一个全局的QThreadPool实例,可以通过QThreadPool::globalInstance()访问。

三、QThreadPool的主要方法

1、void start(QRunnable *runnable, int priority = 0);

将任务(QRunnable对象)添加到线程池中执行 

2、bool tryStart(QRunnable *runnable);

尝试立即执行任务。如果没有可以线程,返回false 

3、 bool waitForDone(int msecs = -1);

阻塞当前线程,直到所有任务完成 

4、void setMaxThreadCount(int maxThreadCount); 

设置线程池最大线程池数 

5、 int activeThreadCount() const;

返回当前正执行任务的线程数 

6、 static QThreadPool *globalInstance(); 

返回全局的QThreadPool实例 

7、 void setExpiryTimeout(int expiryTimeout);

设置线程池中线程的过期时间(以毫秒为单位),当一个线程在指定时间内没有执行任务时,线程池会将该线程销毁,以减少资源占用。如果为负值(默认),则新创建的线程不会过期,即在线程池销毁之前,线程不会退出。

8、  void clear();

 清楚线程池,从队列中移除尚未启动的runnable

四、QRunnable类

        QThreadPool的任务是通过QRunnable对象表示的。QRunnable是一个抽象基类,需要继承它并实现run()方法来定义任务的具体逻辑。 

1、 virtual void run() = 0;

纯虚函数,子类必须实现。定义任务的具体逻辑

2、 void setAutoDelete(bool _autoDelete) { ref = _autoDelete ? 0 : -1; }

设置任务完成后是否自动删除,默认值为true。这个标志必须在调用QThread::strart()之前设置。在之后调用将出现未定义行为。

3、 bool autoDelete() const { return ref != -1; }

返回任务是否自动删除 

五、使用QThreadPool的步骤

1、创建任务:继承QRunnable并实现run()方法

// 自定义任务类
class MyTask : public QRunnable
{
public:MyTask(int id) : m_id(id) {}void run() override {qDebug() << "Task" << m_id << "started in thread" << QThread::currentThreadId();QThread::sleep(2); // 模拟耗时操作qDebug() << "Task" << m_id << "finished in thread" << QThread::currentThreadId();}private:int m_id;
};

2、将任务提交到线程池:使用QThreadPool::start()

    // 获取全局线程池QThreadPool* pool = QThreadPool::globalInstance();// 设置线程池的最大线程数pool->setMaxThreadCount(3);// 创建并提交任务for (int i = 0; i < 10; ++i) {MyTask* task = new MyTask(i);pool->start(task);}

3、等待任务完成(可选):使用QThreadPool::waitForDone()阻塞当前线程,直到所有任务完成 

    // 等待所有任务完成qDebug() << "Waiting for tasks to finish...";pool->waitForDone();qDebug() << "All tasks finished!";

 六、完整代码

#include <QCoreApplication>
#include <QThreadPool>
#include <QRunnable>
#include <QDebug>
#include <QThread>// 自定义任务类
class MyTask : public QRunnable
{
public:MyTask(int id) : m_id(id) {}void run() override {qDebug() << "Task" << m_id << "started in thread" << QThread::currentThreadId();QThread::sleep(2); // 模拟耗时操作qDebug() << "Task" << m_id << "finished in thread" << QThread::currentThreadId();}private:int m_id;
};int main(int argc, char *argv[])
{QCoreApplication app(argc, argv);// 获取全局线程池QThreadPool* pool = QThreadPool::globalInstance();// 设置线程池的最大线程数pool->setMaxThreadCount(3);// 创建并提交任务for (int i = 0; i < 10; ++i) {MyTask* task = new MyTask(i);pool->start(task);}// 等待所有任务完成qDebug() << "Waiting for tasks to finish...";pool->waitForDone();qDebug() << "All tasks finished!";return 0;
}

 七、运行结果

Task 0 started in thread 0x1a34
Task 1 started in thread 0x1a38
Task 2 started in thread 0x1a3c
Task 0 finished in thread 0x1a34
Task 3 started in thread 0x1a34
Task 1 finished in thread 0x1a38
Task 4 started in thread 0x1a38
Task 2 finished in thread 0x1a3c
Task 5 started in thread 0x1a3c
...
All tasks finished!

说明:线程池最多同时运行三个任务。当一个任务完成后,线程池会立即从队列中取出下一个任务执行。

八、注意事项

1、任务的生命周期

(1)如果QRunnable的autoDelete()为true(默认值),任务完成后会自动删除。

(2)如果需要在任务完成后手动管理内存,可以将autoDelete()设置为false。

2、线程池的大小

(1)默认情况下,QThreadPool的最大线程数为CPU核心数。

(2)可以通过setMaxThreadCount()调整线程池大小

九、总结

1、QThreadPool是Qt中用于管理线程池的类,适合处理大量短期的任务

2、通过QRunnable定义任务逻辑,并使用QThreadPool提交任务

3、可以设置线程池大小、等待任务完成,并管理任务的生命周期

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python爬虫:WebAssembly案例分析与爬取实战

文章目录 一、WebAssembly简介1.1 什么是WebAssembly?1.2 WebAssembly的优势1.3 WebAssembly 的使用场景1.4 WebAssembly 对爬虫的挑战二、WebAssembly案例分析2.1 案例一:在线游戏2.2 案例二:图像处理应用三、Python爬虫实战:处理WebAssembly模块3.1 案例一3.2 案例二四、…

vue3配置端口,比底部vue调试

import { fileURLToPath, URL } from ‘node:url’ import { defineConfig } from ‘vite’ import vue from ‘vitejs/plugin-vue’ import vueJsx from ‘vitejs/plugin-vue-jsx’ // 关闭vue底部调试模式 // import vueDevTools from ‘vite-plugin-vue-devtools’ // htt…

算法仿真平台搭建1-FFMPEG+RtspSever快速搭建一个RTSP服务器

一、前言 本文相关的全部源码和RtspSever库&#xff0c;我已打包上传&#xff0c;欢迎大家免费下载&#xff0c;testRTSPSever。 每一个嵌入式视觉算法工程师&#xff0c;都应该有一套属于自己的算法仿真和测试环境。可以方便地进行视频、图像等素材进行在线导入&#xff0c;可…

大模型WebUI:Gradio全解12——LangChain原理、架构和组件(2)

大模型WebUI:Gradio全解12——LangChain原理、架构和组件(2) 前言12. LangChain原理及agents构建Gradio UI12.2 学习资料12.2.1 学习文档12.2.2 用途示例12.2.3 OpenAI和DeepSeek例程1. OpenAI示例2. DeepSeek例程参考文献前言 本系列文章主要介绍WEB界面工具Gradio。Gradi…

盛京开源社区加入 GitCode,书写东北开源生态新篇章

在数字化转型与开源技术蓬勃发展的浪潮下&#xff0c;开源社区已成为推动技术创新的核心力量。盛京开源社区&#xff08;SJOSC&#xff09;作为沈阳地区的开源交流平台&#xff0c;始终致力于连接开发者、企业及高校&#xff0c;构建区域技术生态圈。 现在&#xff0c;盛京开源…

安装Git(小白也会装)

一、官网下载&#xff1a;Git 1.依次点击&#xff08;红框&#xff09; 不要安装在C盘了&#xff0c;要炸了&#xff01;&#xff01;&#xff01; 后面都 使用默认就好了&#xff0c;不用改&#xff0c;直接Next&#xff01; 直到这里&#xff0c;选第一个 这两种选项的区别如…

Vue.js计算属性

计算属性​ 基础示例​ 模板中的表达式虽然方便,但也只能用来做简单的操作。如果在模板中写太多逻辑,会让模板变得臃肿,难以维护。比如说,我们有这样一个包含嵌套数组的对象: js const author = reactive({name: John Doe,books: [Vue 2 - Advanced Guide,Vue 3 - Bas…

代码审计入门学习

简介 HadSky轻论坛程序为个人原创PHP系统&#xff0c;作者为蒲乐天&#xff0c;后端基于puyuetianPHP框架驱动&#xff0c;前端基于 puyuetianUI框架驱动&#xff0c;默认编辑器为puyuetianEditor富文本编辑器&#xff0c;其他非原创框架及驱动JQuery.js 及Font-Awesome字体库…

测试金蝶云的OpenAPI

如何使用Postman测试K3Cloud的OpenAPI 1. 引言 在本篇博客中&#xff0c;我将带你逐步了解如何使用Postman测试和使用K3Cloud的OpenAPI。内容包括下载所需的SDK文件、配置文件、API调用及测试等步骤。让我们开始吧&#xff01; 2. 下载所需的SDK文件 2.1 获取SDK 首先&…

【愚公系列】《Python网络爬虫从入门到精通》034-DataFrame简单数据计算整理

标题详情作者简介愚公搬代码头衔华为云特约编辑,华为云云享专家,华为开发者专家,华为产品云测专家,CSDN博客专家,CSDN商业化专家,阿里云专家博主,阿里云签约作者,腾讯云优秀博主,腾讯云内容共创官,掘金优秀博主,亚马逊技领云博主,51CTO博客专家等。近期荣誉2022年度…

服务端驱动UI架构解析:React Server Components与流式渲染的革命

引言&#xff1a;重新定义前后端边界 Shopify采用React Server Components后&#xff0c;动态模块加载速度提升340%&#xff0c;客户端Bundle减少62%。Discord重构消息流服务&#xff0c;通过流式渲染使首屏TTI从4.2s降至1.1s。Vercel生产数据显示&#xff0c;混合渲染技术让L…

顶顶通呼叫中心中间件(mod_cti基于FreeSWITCH)-大模型电话机器人

语音流直接对接Realtime API 多模态大模型 直接把音频流输出给大模型&#xff0c;大模型返回音频流。 顶顶通CTI对Realtime API 的支持 提供了以下2个APP可对接任意 •cti_audio_stream 通过TCP推流和播放流&#xff0c;适合用于人机对话场景。 •cti_unicast_start 通过旁…

绕过 RAG 实时检索瓶颈,缓存增强生成(CAG)如何助力性能突破?

编者按&#xff1a; 你是否曾经遇到过这样的困扰&#xff1a;在开发基于 RAG 的应用时&#xff0c;实时检索的延迟让用户体验大打折扣&#xff1f;或者在处理复杂查询时&#xff0c;检索结果的不准确导致回答质量不尽如人意&#xff1f; 在当前大语言模型应用大规模落地的背景下…

后端返回文件流,前端导出excel文件

1、当后端接口返回文件流时&#xff0c;需前端导出excel文件&#xff0c;在请求中添加 responseType: blob限制条件&#xff0c;根据返回的文件流导出 封装的方法&#xff1a; /** * 公共的导出excel方法 * param {*} content 后端接口返回的二进制文件 * param {*} name 导出…

基于django图书信息管理系统的搭建(增删改查)

✍django项目搭建教程 ☞ ----------------- 教程 本文主要讲解django如何连接数据库MySQL并且可视化展示&#xff0c;实现增删改查功能 目录 一. 创建django应用 二. 数据库配置 三. 查看数据库 四. 编写代码 4.1视图函数 4.2 配置URL 4.3创建模板文件 4.…

鸿蒙NEXT开发-元服务和服务卡片的开发

注意&#xff1a;博主有个鸿蒙专栏&#xff0c;里面从上到下有关于鸿蒙next的教学文档&#xff0c;大家感兴趣可以学习下 如果大家觉得博主文章写的好的话&#xff0c;可以点下关注&#xff0c;博主会一直更新鸿蒙next相关知识 目录 1. 元服务基本概念 1.1 基本介绍 1.2 元…

HBuilder X中,uni-app、js的延时操作及定时器

完整源码下载 https://download.csdn.net/download/luckyext/90430165 在HBuilder X中&#xff0c;uni-app、js的延时操作及定时器可以用setTimeout和setInterval这两个函数来实现。 1.setTimeout函数用于在指定的毫秒数后执行一次函数。 例如&#xff0c; 2秒后弹出一个提…

IP属地是通过卫星定位的吗?如何保护用户隐私

在数字时代&#xff0c;网络空间成为了人们日常生活不可或缺的一部分。随着社交媒体、在线服务等平台的兴起&#xff0c;用户IP属地信息的重要性日益凸显。然而&#xff0c;关于IP属地是如何确定的&#xff0c;尤其是是否通过卫星定位这一问题&#xff0c;却常常引发公众的疑问…

DMA发送全部历史记录数据到串口

背景 博主参与的项目中&#xff0c;有个读取全部历史记录的功能&#xff0c;如果下位机在主程序中将全部历史记录单纯地通过串口传输会比较占用cpu资源&#xff0c;影响主程序中别的功能。最后商量得出以下实现方案&#xff1a; 定义两个发送缓冲区DMATxbuf1和DMATxbuf2&…

华为云之使用鲲鹏弹性云服务器部署Node.js环境【玩转华为云】

华为云之使用鲲鹏弹性云服务器部署Node.js环境【玩转华为云】 一、本次实践介绍1.1 实践环境简介1.3 本次实践完成目标 二、 相关服务介绍2.1 华为云ECS云服务器介绍2.2 Node.js介绍 三、环境准备工作3.1 预置实验环境3.2 查看预置环境信息 四、登录华为云4.1 登录华为云4.2 查…