Python自定义线程池,这么高效,是不是开了挂?

目录

1、线程池基础 🏗️

1.1 线程池概念与优势

1.2 Python标准库concurrent.futures简介

示例代码:使用ThreadPoolExecutor执行简单任务

2、利用ThreadPoolExecutor定制 🎛️

2.1 创建自定义线程池类

示例代码:自定义ThreadPoolExecutor子类

2.2 设置线程池参数与任务提交

示例代码:配置线程池并提交任务

2.3 错误处理与结果回调

示例代码:使用add_done_callback处理异常

3、从零开始实现线程池 🌀

3.1 设计线程池架构

3.2 实现任务队列与工作线程

任务队列实现

工作线程实现

3.3 线程同步与安全控制

4、集成异步IO与线程池 🌐

4.1 asyncio与线程池混用技巧

示例代码:混合使用asyncio与ThreadPoolExecutor

4.2 提升I/O密集型任务性能

示例代码:异步并发下载网页

4.3 实战案例:并发下载与处理

示例代码:并发下载图片并转换为灰度

5、优化与监控策略 📊

5.1 动态调整线程池大小

示例代码:基于任务队列长度动态调整线程池

5.2 监控线程池状态与性能指标

实施方案:

5.3 日志记录与异常报警

示例代码:集成日志记录与异常处理

6、总结 🎯



1、线程池基础 🏗️

1.1 线程池概念与优势

线程池是一种软件设计模式,用于管理多个线程的创建、执行、销毁等生命周期 ,从而提高程序性能与资源利用率。它预先创建一定数量的工作线程并保持就绪状态 ,当有任务到达时 ,线程池会从队列中取出任务并分配给空闲线程执行 ,执行完毕后线程不会立即销毁而是回到池中等待下一轮任务。这一机制有效减少了频繁创建和销毁线程的开销,提升了系统的响应速度和吞吐量。

优势包括:

  • • 资源高效:减少线程创建与销毁的开销。

  • • 控制并发:通过线程池大小限制并发任务数,防止资源过度消耗。

  • • 管理便利:统一调度任务,便于监控与控制。

  • • 提升响应:复用已有线程,加快任务处理速度。

1.2 Python标准库concurrent.futures简介

concurrent.futures模块自Python 3.2起被引入,为异步执行提供了高层次的接口,包括两种主要的执行器:ThreadPoolExecutor用于多线程并发,而ProcessPoolExecutor则用于多进程。对于自定义线程池的需求,ThreadPoolExecutor是理想的起点。

ThreadPoolExecutor允许开发者轻松创建线程池,提交任务 ,并获取结果,支持同步等待(result())和异步获取结果(add_done_callback()), 提供了异常处理机制以及对任务完成情况的追踪。

示例代码:使用ThreadPoolExecutor执行简单任务

下面是一个使用ThreadPoolExecutor的示例,展示了如何创建一个线程池,提交任务,并获取结果。

import concurrent
from concurrent.futures import ThreadPoolExecutor
import timedef long_running_task(n):"""模拟耗时操作"""time.sleep(n)return f"Task {n} done after {n} seconds."# 创建一个包含4个线程的线程池
with ThreadPoolExecutor(max_workers=4)as executor:# 提交任务到线程池futures ={executor.submit(long_running_task, n)for n in range(5)}# 收集结果
for future in concurrent.futures.as_completed(futures):print(future.result())

此段代码中,long_running_task模拟了一个耗时操作,通过线程池提交了5个这样的任务。每个任务在完成后打印其结果,由于线程池最大工作者数为4,因此前四个任务会立即开始执行 ,最后一个任务会在某个线程释放后继续。

请注意,实际应用中应根据具体需求调整线程池大小及任务细节。

2、利用ThreadPoolExecutor定制 🎛️

2.1 创建自定义线程池类

为了更好地控制线程池的行为,我们可以创建一个自定义的ThreadPoolExecutor子类。这不仅允许我们覆盖默认行为,还能添加额外的功能,如更详细的日志记录、错误处理策略以及线程池状态的监控。

示例代码:自定义ThreadPoolExecutor子类

下面的代码展示了如何创建一个自定义的ThreadPoolExecutor子类 ,其中增加了初始化时的参数验证以及更丰富的日志记录功能。

from concurrent.futures import ThreadPoolExecutor
import loggingclass CustomThreadPoolExecutor(ThreadPoolExecutor):def __init__(self, max_workers=None, thread_name_prefix='', initializer=None, initargs=()):if max_workers is None or max_workers <=0:raise ValueError("max_workers must be greater than 0")super().__init__(max_workers=max_workers,thread_name_prefix=thread_name_prefix, initializer=initializer,initargs=initargs)self.logger = logging.getLogger(__name__)self.logger.setLevel(logging.INFO)def submit(self, fn, *args, **kwargs):future =super().submit(fn,*args,**kwargs)self.logger.info(f"Submitted task: {fn.__name__} with args: {args} and kwargs: {kwargs}")return future# 使用自定义线程池执行任务
with CustomThreadPoolExecutor(max_workers=4, thread_name_prefix="CustomThread")as executor:futures =[executor.submit(pow, base, exponent)for base, exponent in[(2,10),(3,5)]]
for future in futures:print(f"Result: {future.result()}")

输出:

Result: 1024
Result: 243

 

在这个示例中,我们首先检查max_workers是否有效,然后初始化父类ThreadPoolExecutor。我们还设置了一个logger,用于记录任务的提交情况。submit方法被重写 ,以便在任务提交时记录相关信息。

2.2 设置线程池参数与任务提交

在创建线程池时,可以通过参数max_workers来指定线程池中的最大线程数。此外,还可以通过thread_name_prefix来设置线程名前缀,便于调试和日志分析。

示例代码:配置线程池并提交任务

下面的代码示例展示了如何配置线程池并提交多个任务,同时展示了如何使用as_completed函数来获取已完成的任务结果。

from concurrent.futures import ThreadPoolExecutor, as_completeddef calculate_factorial(number):factorial =1for i in range(1, number +1):factorial *= ireturn factorialwith ThreadPoolExecutor(max_workers=5)as executor:tasks =[executor.submit(calculate_factorial, n)for n in range(1,6)]for future in as_completed(tasks):result = future.result()
print(f"The factorial of {future._args[0]} is {result}")

这个示例中 ,我们定义了一个calculate_factorial函数来计算阶乘,然后使用ThreadPoolExecutor创建了一个包含5个线程的线程池。我们提交了5个任务,分别计算1到5的阶乘 ,并使用as_completed来迭代并打印出每个任务的结果。

2.3 错误处理与结果回调

在处理

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

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

相关文章

四.iOS核心动画 - 图层的视觉效果

引言 在前几篇博客中我们讨论了图层的frame,bounds,position以及让图层加载图片。但是图层事实上不仅可以显示图片&#xff0c;或者规则的矩形块&#xff0c;它还有一系列内建的特性来创建美丽优雅的页面元素。在这篇博客中我们就来探索一下CALayer的视觉效果。 视觉效果 图…

java笔记(29)——动态代理(工厂模式)【示例】

文章目录 动态代理&#xff08;工厂模式&#xff09;接口类实体类代理类测试类 动态代理&#xff08;工厂模式&#xff09; 接口类 package com.itchen.proxytest;public interface Star {public abstract String sing(String name);public abstract void dance(); }实体类 …

转化分析|一位数据分析师的实验田复盘

花3个月时间&#xff0c;吭哧吭哧写了80页草稿的《投资——1. 知己知彼》&#xff0c;发布之前豪言壮语“2000阅读量”&#xff0c;到现在累计72&#xff0c;真是piapia打脸&#xff01;心态那个崩啊&#xff01;&#xff01; 朋友们吐槽内容太长、定位不明确、分析深度不够&am…

手持式雷达流速仪的工作原理

TH-LS5手持式雷达流速仪基于雷达技术和多普勒效应进行工作。它发射一束微波信号到水体表面&#xff0c;当信号遇到水流时&#xff0c;会发生多普勒频移。发射器发出的高频电磁波信号(通常是微波信号)遇到流体后&#xff0c;部分信号会被反射回来。接收器接收到反射回来的信号&a…

开发一套java语言的智能导诊需要什么技术?java+ springboot+ mysql+ IDEA互联网智能3D导诊系统源码

开发一套java语言的智能导诊需要什么技术&#xff1f;java springboot mysql IDEA互联网智能3D导诊系统源码 医院导诊系统是一种基于互联网和3D人体的智能化服务系统&#xff0c;旨在为患者提供精准、便捷的医院就诊咨询服务。该系统整合了医院的各种医疗服务资&#xff1b;智慧…

android gradle开发与应用(-)基础

Gradle 是一个强大的自动化构建工具&#xff0c;广泛用于多种编程语言和平台&#xff0c;尤其是在 Android 应用开发中。Android Studio&#xff0c;作为官方的 Android 开发环境&#xff0c;使用 Gradle 作为其构建系统。了解 Gradle 的基础对于有效地管理和构建 Android 项目…

【机器学习】机器学习与医疗健康在疾病预测中的融合应用与性能优化新探索

文章目录 引言第一章&#xff1a;机器学习在医疗健康中的应用1.1 数据预处理1.1.1 数据清洗1.1.2 数据归一化1.1.3 特征工程 1.2 模型选择1.2.1 逻辑回归1.2.2 决策树1.2.3 随机森林1.2.4 支持向量机1.2.5 神经网络 1.3 模型训练1.3.1 梯度下降1.3.2 随机梯度下降1.3.3 Adam优化…

【你也能从零基础学会网站开发】(了解)关系型数据库的基本架构体系结构与概念理解

&#x1f680; 个人主页 极客小俊 ✍&#x1f3fb; 作者简介&#xff1a;程序猿、设计师、技术分享 &#x1f40b; 希望大家多多支持, 我们一起学习和进步&#xff01; &#x1f3c5; 欢迎评论 ❤️点赞&#x1f4ac;评论 &#x1f4c2;收藏 &#x1f4c2;加关注 关系型数据库的…

【第五节】C/C++数据结构之图

目录 一、图的基本概念 1.1 图的定义 1.2 图的其他术语概念 二、图的存储结构 2.1 邻接矩阵 2.2 邻接表 三、图的遍历 3.1 广度优先遍历 3.2 深度优先遍历 四、最小生成树 4.1 最小生成树获取策略 4.2 Kruskal算法 4.3 Prim算法 五、最短路径问题 5.1 Dijkstra算…

INFINI Easysearch尝鲜Hands on

INFINI Easysearch 是一个分布式的近实时搜索与分析引擎&#xff0c;核心引擎基于开源的 Apache Lucene。Easysearch 的目标是提供一个自主可控的轻量级的 Elasticsearch 可替代版本&#xff0c;并继续完善和支持更多的企业级功能。 与 Elasticsearch 相比&#xff0c;Easysear…

熊猫烧香是什么?

熊猫烧香&#xff08;Worm.WhBoy.cw&#xff09;是一种由李俊制作的电脑病毒&#xff0c;于2006年底至2007年初在互联网上大规模爆发。这个病毒因其感染后的系统可执行文件图标会变成熊猫举着三根香的模样而得名。熊猫烧香病毒具有自动传播、自动感染硬盘的能力&#xff0c;以及…

上海市计算机学会竞赛平台2023年5月月赛丙组最大子阵和

题目描述 给定 &#x1d45b;&#x1d45b;nn 个整数组成一个方阵 &#x1d44e;&#x1d456;,&#x1d457;ai,j​&#xff0c;请找一个 &#x1d458;&#x1d458;kk 的子方阵&#xff0c;使得子方阵内的数字之和达到最大&#xff0c;输出这个最大值。 输入格式 第一行&…

vue 组件下 img 标签动态传入不展示

效果 解决办法&#xff1a; require() <titleComponent:title"业务工作概览":src"require(/assets/imgs/evaluation/overviewStatistics.png)"></titleComponent> 效果&#xff1a;

Github 上 Star 数最多的大模型应用基础服务 Dify 深度解读(一)

背景介绍 接触过大模型应用开发的研发同学应该都或多或少地听过 Dify 这个大模型应用基础服务&#xff0c;这个项目自从 2023 年上线以来&#xff0c;截止目前&#xff08;2024-6&#xff09;已经获得了 35k 多的 star&#xff0c;是目前大模型应用基础服务中最热门的项目之一…

ss命令详细使用讲解文章

ss 命令作为 iproute2 软件包的一部分&#xff0c;是Socket Statistics的缩写&#xff0c;也称为IPC&#xff08;Inter-process Communication&#xff09;套接字统计 ss命令用于显示sockets&#xff08;套接字&#xff09;的状态。与netstat类似&#xff0c;但它通常提供更详…

WebKit 简介及工作流程探秘

在探索现代互联网世界的奥秘时&#xff0c;浏览器引擎是不可或缺的一环&#xff0c;而 WebKit 正是其中的佼佼者。WebKit&#xff0c;这个开源的浏览器渲染引擎&#xff0c;以其卓越的性能和广泛的支持度&#xff0c;成为了 Safari、早期的 Chrome 以及其他众多浏览器的核心。本…

【笔试记录】华为 | 20230823 | cpp

获取连通的相邻节点列表 题目描述 在网元内&#xff0c;存在了 N 个转发节点&#xff0c;每个转发节点有自己唯一的标识 TB 且每个节点有 M 个端口&#xff0c;节点间通过端口进行报文通讯。出于业务隔离的需求&#xff0c;服务器内的端口被划分为多个通讯平面(用 VLAN 隔离&…

取消lfs, 使用原始文件上传的办法

查询当前仓库使用lfs的文件&#xff0c;然后删除 git lfs ls-files 删除lfs文件后&#xff0c;提交commit git add . git commit -m"remove lfs file" 查询本地lfs配置 git config --local --list 重置本地lfs配置 git config --unset filter.lfs.smudgegit co…

从0到1搭建微服务框架

目录 1.技术栈&#xff1a; 2.模块介绍: 3.关键代码讲解 3.1基础公共模块(common)依赖&#xff1a; 3.3授权模块(auth)依赖: 3.4授权模块核心配置类(AuthrizatonConfig): 3.4 SecurityConfig.java 3.5 bootstrap的核心配置文件(其他服务配置类似这个)&#xff1a; 3.6n…

防爆巡检终端在石化工厂安全保障中的应用

防爆巡检终端在石化工厂安全保障中的应用是广泛而关键的&#xff0c;其设计旨在确保在易燃易爆环境中进行安全、有效的巡检工作。以下是防爆巡检终端在石化工厂安全保障中的详细应用描述&#xff1a; 1. 环境监测与预警 防爆巡检终端配备了各种传感器&#xff0c;能够实时监测…