浅析python多线程及ThreadPoolExecutor的使用及问题

Python线程池模块ThreadPoolExecutor用法分析 这篇文章主要介绍了Python线程池模块ThreadPoolExecutor用法,结合实例形式分析了Python线程池模块ThreadPoolExecutor的导入与基本使用方法,需要的朋友可以参考下 文实例讲述了Python线程池模块ThreadPoolExecutor用法。分享给大家供大家参考,具体如下: python3内置的有Threadingpool和ThreadPoolExecutor模... 阅读详情

首先上一个多线程获取多个excel数据为dataFrame的例子

前言:

本此测试数据为120个excel文件,每个文件1000条数据,共120000条数据需要读取

直接创建线程与使用线程池对比

1. 直接依任务数创建线程
# @datetime:6/27/0027
"desc"
__author__ = "hanyaning@deri.energy"
import threading
import os.path
import time
from service import logger
import pandas as pd

logger = logger.MyLogger("multi_thread").getLogger()
# 定义全局变量,用于每个线程存放data
data = []


# 自定义线程类,继承threading.Thread
class MyThread(threading.Thread):
    def __init__(self, name, path):
        threading.Thread.__init__(self)
        # 线程名
        self.name = name
        # 线程执行任务所需数据定义,这里是excel路径
        self.path = path

    # run方法,执行线程start方法后会自动调用这个run方法,用于调用getExcelData并将值传给data
    def run(self):
        global data
        path = self.path
        data.append(getExcelData(path))


def getExcelData(path):
    logger.info("开始读取excel,当前线程:" + str(threading.currentThread().name))
    data = pd.DataFrame()
    if not os.path.exists(path):
        raise FileNotFoundError()
    if os.path.isfile(path):
        logger.info("读取Excel文件完毕,当前线程:" + str(threading.currentThread().name))
        return data.append(pd.read_excel(path, skiprows=1, skipfooter=1), sort=False)
    return None


if __name__ == "__main__":
    data_frame = pd.DataFrame()
    threads = []

    excel_path = os.path.join(os.getcwd(), "../excels")
    xls_names = [x for x in os.listdir(excel_path) if x.endswith(".xls")]
    startTime = time.time()

    for file_name in xls_names:
        # 获取文件目录下的excel文件,新建线程
        thread = MyThread(str(file_name), os.path.join(excel_path, file_name))
        thread.start()
        threads.append(thread)
    # 这里时用于线程阻塞,等待所有子线程线程执行完毕主线程才继续执行
    for thread in threads:
        thread.join()

    # data转换为dataframe
    for d in data:
        data_frame = data_frame.append(d, sort=False)
    endTime = time.time()
    logger.info(endTime - startTime)
    logger.info(len(data_frame))

执行结果:

耗时:12.755005836486816
获取数据量:120000

2. 使用线程池创建线程获取
# @datetime:6/27/0027
"desc"
__author__ = "hanyaning@deri.energy"
from service import logger
from concurrent.futures import *
import threading
import os
import pandas as pd
import time

logger = logger.MyLogger("multi_process").getLogger()


def getExcelData(path):
    logger.info("开始读取excel,当前线程:" + str(threading.currentThread().name))
    data = pd.DataFrame()
    if not os.path.exists(path):
        raise FileNotFoundError()
    if os.path.isfile(path):
        logger.info("读取Excel文件完毕,当前线程:" + str(threading.currentThread().name))
    return data.append(pd.read_excel(path, skiprows=1, skipfooter=1), sort=False)


if __name__ == "__main__":
    excel_path = os.path.join(os.getcwd(), "../excels")
    xls_names = [x for x in os.listdir(excel_path) if x.endswith(".xls")]
    startTime = time.time()
    executor = ThreadPoolExecutor(max_workers=10)
    # 通过submit函数提交执行的函数到线程池中,submit函数立即返回,不阻塞
    return_data = []
    # 分配任务
    all_task = [executor.submit(getExcelData, os.path.join(excel_path, file_name)) for file_name in xls_names]
    data = pd.DataFrame()
    # 每有一个线程执行完获取返回值,直接调用concurrent.futures的as_completed方法可以实现
    for future in as_completed(all_task):
        data = data.append(future.result())
    # 等待子线程执行完
    wait(all_task)

    end = time.time()
    logger.info(len(data))
    logger.info(end - startTime)

执行结果:

耗时:12.771236181259155

将最大线程数量(max_workers=120)设置为120后:

耗时:12.948451519012451

3. 单线程直接获取
# @datetime:6/27/0027
"desc"
__author__ = "hanyaning@deri.energy"
import os.path
import time
from service import logger
import pandas as pd

logger = logger.MyLogger("excelUtils").getLogger()


class ExcelReader:

    def __init__(self, path, file_suffix=".xls"):
        self.path = path
        self.file_suffix = file_suffix

    def getData(self):
        if not os.path.exists(self.path):
            raise FileNotFoundError()
        data = pd.DataFrame()
        if os.path.isdir(self.path):
            xls_names = [x for x in os.listdir(self.path) if x.endswith(self.file_suffix)]
            logger.info("开始")
            for xls_name in xls_names:
                df = pd.read_excel(os.path.join(self.path, xls_name), skiprows=1, skipfooter=1)
                data = data.append(df, sort=False)
            logger.info("读取Excel文件完毕,共读取" + str(xls_names.__len__()) + "个文件")
        return data


if __name__ == "__main__":
    start = time.time()
    reader = ExcelReader(os.path.join(os.getcwd(), "../excels"))
    data = reader.getData()
    end = time.time()
    print(end - start)
    print(len(data))

结果:

耗时:12.019948959350586

结论:单线程 < 多线程 = 使用线程池(10)<使用线程池(120)

happy 不?python中使用多线程耗时比单线程还多了,不能怪python,不得不谈一下GIL

GIL是什么

首先GIL不是python的特性,二十Cpython(python解析器)所使用的一个概念。实际上各大环境基本上都使用了Cpython解释器。

GIL全称Global Interpreter Lock,通俗点说就是一把超级大锁,即全局排他锁,保护了数据安全性的同时,使得多线程提高效率的能力几乎丧失,尤其表现在cpu密集型计算上。结果方法之一时python提供了mutiprocess(多进程)来弥补这个问题,由于多个进程之间的时不同的GIL锁,不会发生阻塞。

关于GIL,可以参见这篇博文[python中的GIL详解]

Python实现7z/ZIP压缩包密码破解:从原理到多线程实战 数据加密与密码验证是信息安全领域的核心基础。对称加密算法通过密钥对数据进行加解密,而密码破解本质上是对验证机制的逆向模拟。在数据恢复与安全测试场景中,基于字典的暴力破解技术具有重要实用价值。Python凭借其丰富的库生态和简洁语法,成为实现此类工具的理想选择。通过zipfile和py7zr库处理不同格式的压缩包,结合concurrent.futures实现多线程并发,可以构建高效的密码尝试引擎。本文以7z和ZIP格式为例,深入讲解密码验证原理、字典生成策略和线程池优化技巧,帮助开发者掌握数据恢复工具的实现逻 阅读详情

相关推荐

CVE-2025-53770漏洞扫描器开发实战:从原理到Python实现

在网络安全领域,漏洞扫描是识别和评估系统风险的核心技术。其原理是通过构造特定网络请求,探测目标系统是否存在已知的安全缺陷。这项技术的价值在于能够自动化、大规模地进行安全检测,为风险评估和应急响应提供关键数据支撑,广泛应用于企业安全自查、渗透测试等场景。针对近期备受关注的微软SharePoint高危漏洞CVE-2025-53770,通用扫描器往往存在响应延迟和检测精度不足的问题。本文聚焦于开发一款轻量级、高精度的专项扫描器,详细阐述了如何利用Python的requests库和多线程架构,设计包含指纹识别与安全

weixin_33802505的博客 373

python的线程池需要关闭吗_Python线程池

介绍系統启动了一个新线程的成本是比较高的,因为它涉及到与操作系统的交互。在这种情形下,使用线程池可以很好的提升性能,尤其是当程序中需要创建大量生存期很短暂的线程的时候,更应该考虑使用线程池线程池在系统启动的时候即创建大量空闲的线程,程序只要将一个函数提交给线程池,线程池就会启动一个空闲的线程来执行它,该线程并不会死亡,而是再次返回到线程池中变为空闲状态,等待执行下一个函数此外,使用线程池可以有效地...

weixin_42285866的博客 1839

Python实战:解析B站DASH流媒体协议,构建高效视频下载工具

在Python网络编程与数据抓取领域,requests库和正则表达式是处理HTTP请求与文本解析的基础工具。其原理在于模拟浏览器行为,通过发送携带特定请求头的HTTP请求,获取目标网页的HTML或JSON数据,再利用正则表达式或解析库提取关键信息。这项技术的核心价值在于能够自动化获取和处理网络公开数据,极大地提升了数据采集与处理的效率。在众多应用场景中,流媒体视频内容的分析与下载是一个典型实践,它涉及对现代视频网站普遍采用的DASH(Dynamic Adaptive Streaming over HTTP)

weixin_30613343的博客 579

Python ThreadPoolExecutor 任务队列阻塞提交

分享一个ThreadPoolExecutor中阻塞提交任务队列的小例子,保证充分利用线程资源的同时防止队列中任务过多导致内存占用过大。

Keithen的摸鱼记录 3707

Python键盘监听与自动化脚本开发:从pynput入门到热键管理器实战

键盘监听是自动化技术中的基础概念,它通过捕获系统级按键事件实现程序与用户的交互。其原理是利用操作系统提供的钩子(Hook)API,在后台线程中监控全局键盘输入,区分按键的按下(press)与释放(release)状态。这项技术的核心价值在于将重复性手动操作转化为自动化流程,极大提升办公、开发和日常使用效率。在Python生态中,pynput库因其跨平台特性和对组合键的精细控制,成为实现键盘监听的首选工具。通过维护一个按键状态机,开发者可以可靠地监听如Ctrl+Shift+A等复杂组合键,并触发自定义的自动化

weixin_34080951的博客 438

UnityPy实战指南:Python解析与提取Unity游戏资源

在游戏开发与逆向工程领域,资源提取与解析是一项基础且关键的技术。其核心原理在于对游戏资源包的序列化格式进行解析,将二进制数据还原为可读的结构化信息。这项技术的价值在于赋能开发者、研究者与爱好者进行游戏数据分析、Mod制作、本地化汉化以及资源复用。通过Python生态中的强大工具,可以实现对Unity引擎生成的.assets、.assetbundle等资源文件的自动化、批量化操作。UnityPy作为一个纯Python库,正是这一技术实践的优秀代表。它基于逆向工程与格式解析,能够高效读取、修改Unity资源,并

weixin_30279671的博客 507

Python PyQT QThreadPool 线程池运行后整个界面卡死问题

最近在写Excel按照模板生成工具。 使用的环境:python3.7 + PYQT5 + MSsql +xlwings +json 线程池情况下PyQt程序卡死,断点情况下可以运行,不断点情况下直接卡死

Hn的网站都别抢 5283

浅析Python自带的线程池和进程池

线程池和进程池是Python中实现并发编程的重要工具,它们可以有效地管理和调度多线程或多进程执行任务,提高程序的性能和响应能力。在选择使用线程池还是进程池时,需要根据具体的应用场景和需求来决定。对于I/O密集型任务,线程池是一个不错的选择;而对于CPU密集型任务,尤其是需要利用多核资源的情况,进程池更为合适。同时,我们也需要注意线程池和进程池在使用中可能遇到的问题,如线程间的竞态条件、进程间的通信开销等,并采取相应的措施来解决这些问题。

这家伙很懒,什么都没有留下 1763

Python多线程与多进程浅析之三

原文链接 摘要: 基于 I/O 的多线程 多线程的例子中比较多的就是抓取网页,因为抓取网页是典型的 I/O 开销,因此 Python 的多线程终于不显得那么鸡肋了。 我们把上面例子中的计算函数修改为抓取网站的大小。先用最标准的方式,不用线程。 基于 I/O 的多线程 多线程的例子中比较多的就是抓取网页,因为抓取网页是典型的 I/O 开销,因此 Python 的多线程终于不显得那么鸡肋了。 ...

weixin_40581980的博客 194

【QT+VS】如何在现有VS项目中添加Qt界面?【全网最详细】

VS项目有了,就缺个QT界面,怎么办呢?这篇文章帮你一键搞定!

深耕CV 4984

ChatBI告别“NL2SQL依赖症”!从准确率50%到90%,3大技术路线+4个企业案例拆解核心玩法

摘要: ChatBI通过自然语言交互实现数据民主化,其核心是“语义理解+数据执行+知识沉淀”的全链路能力,而非单一的NL2SQL技术。行业采用三大技术路线提升准确率:专有知识库(提升30%)、指标标签语义层(准确率85%)、JSON中间层(多轮对话提升25%)。数据执行方案包括NL2SQL、NL2API等,需结合场景选择。企业落地需解决四大痛点:跨表查询准确率低(引入拓扑图)、模糊查询(用户干预机制)、响应慢(预计算缓存)、多轮对话(上下文池)。Spring AI Alibaba提供轻量级集成方案,助力企业

weixin_52610848的博客 1655

浅析Python多线程

学习Python多线程的资料很多,吐槽Python多线程的博客也不少。本文主要介绍Python多线程实际应用,且假设读者已经了解多线程的基本概念。如果读者对进程线程概念不甚了解,可参见知名博主 阮一峰 转译的一篇博客:《进程与线程的一个简单解释》。 1 线程的基本操作 Python中多线程主要有两个模块,_thread和threading模块。前者更底层,后者更常用,能满足绝大部分编程需求,今...

weixin_30606669的博客 187

第1部分 基础算法(提高篇)--第2章 二分与三分1439:【SCOI2010】传送带

1439:【SCOI2010】传送带 时间限制: 2000 ms 内存限制: 65536 KB 提交数: 372 通过数: 212 【题目描述】 在一个2维平面上有两条传送带,每一条传送带可以看成是一条线段。两条传送带分别为线段AB和线段CD。lxhgww在AB上的移动速度为P,在CD上的移动速度为Q,在平面上的移动速度R。现在lxhgww想从A点走到D点,他想知道最少需要走多长时间。 【输入】 输入数据第一行是4个整数,表示A和B的坐标,分别为Ax,Ay,Bx,By 第二行是4个整

zqhf123的博客 838

一篇文章浅析Python自带的线程池和进程池

击上方“Python爬虫与数据挖掘”,进行关注回复“书籍”即可获赠Python从入门到进阶共10本电子书今日鸡汤岩扉松径长寂寥,惟有幽人自来去。前言大家好,我是星期八。我们都知道,不管是J...

pdcfighting的博客 451

2d游戏地图编辑器_[U3D]基于MarchingCubes实现的War3Editor 地表/悬崖编辑器

花了几天时间研究清楚Marching cubes后,发现这个方法是一个非常适用于地图编辑,网格编辑,procedural 生成的工具。最大的优点有着较好的边缘,表面处理。然后我用U3D写了一个悬崖/地表的编辑器。其中使用到了Marching Cubes的2.5D,2D两种降维的方法。talk is cheap,让我看效果!DemoEditor展示https://www.zhihu.com/vide...

weixin_42504649的博客 1178

计算机组成原理(第三版)唐朔飞-第四章存储器-课后习题

计算机组成原理(第三版)唐朔飞-第四章存储器-课后习题

weixin_45735391的博客 17万+

多线程从入门到放弃

在前面《python多线程浅析》一文中,我比较笼统的写了关于多线程的一些东西,本文准备比较详细的介绍一下多线程,从最基础的创建多线程开始,探讨关于锁、通信机制、线程池等内容! 单线程、多线程、多进程的对比 首先,我们通过以下四个场景,来对比以下单线程、多线程、多进程处理能力的强弱!四个场景分别是CPU计算密集型、磁盘IO密集型、网络IO密集型、还有我们模拟的IO密集型。代码如下: impo...

iva_brother的博客 484

十八万字《python从零到精通教程》第二版,贴心保姆教你从零变大神,学不会找我

文章目录一.pycharm下载安装二.python下载安装三.pycharm上配置python四.配置镜像源让你下载嗖嗖的快4.1pycharm内部配置4.2手动添加镜像源4.3永久配置镜像源五.插件安装(比如汉化?)5.1自动补码神器第一款5.2 自动补码神器第二款5.2汉化pycharm5.3其它插件六.美女背景七.自定义脚本开头八、这个前言一定要看九、python入门十、python缩进十一、Python注释1.单行注释2.多行注释十二、Python 变量1.变量定义理解2. 变量名命名3. 分配多个

全栈川川 7万+

Python实战:利用pypdf与PyMuPDF解密加密PDF文件的技术分析与实现

PDF加密是文档安全保护的基础技术,其核心原理基于密码学中的对称加密算法(如RC4、AES)和哈希函数。通过用户密码派生加密密钥,实现对文档内容的访问控制。在工程实践中,当遇到合法合规的密码恢复需求时,Python凭借其丰富的生态库成为高效工具。pypdf和PyMuPDF等库提供了完整的PDF解析与解密API,结合多线程并发技术,可构建智能密码猜测脚本。本文以加密PDF解密为具体场景,深入探讨了密码生成策略、解密流程优化及常见问题排查,展示了Python在文件安全处理领域的实用价值。

chuiqi9947的博客 389

使用VNA(Vector Network Analyzer)对S参数进行去嵌(二)

无论是使用 EM 仿真工具创建的简化模型(如一段理想传输线)还是复杂模型用于测试夹具,现在都需要使用该 S 参数模型执行去嵌入过程。

小孟同学的博客 6108

2026年医疗AI的可信革命全栈实现(上)

医疗AI可信化:贝叶斯网络与向量数据库的协同架构 本文探讨2026年医疗AI发展的关键转折点——从追求生成能力转向构建可信决策系统。核心观点认为,医疗AI下一阶段的竞争焦点在于不确定性量化和错误传播约束,而非单纯的问答流畅度。研究提出以Python为开发语言、结合向量数据库与贝叶斯网络的混合架构: 技术分层 语言层(LLM):处理自然语言交互与工具调用 证据层(Milvus/Qdrant):实现可审计的临床知识检索 概率层(pgmpy/PyMC):执行贝叶斯推理与风险路由 治理层:确保权限控制与人工复核机制

AllenLV的博客 1151

Python解析PDF:从基础原理到两栏文档精准提取实战

PDF文档解析是数据处理与自动化流程中的关键技术,其核心在于理解PDF作为固定布局格式的内部结构与渲染逻辑。PDF本质上是一种基于坐标的页面描述语言,程序化提取文本需突破其视觉呈现顺序与逻辑阅读顺序不一致的障碍,这涉及字符坐标提取、版面分析与文本流重组等原理。在Python生态中,PyPDF2、pdfplumber和PyMuPDF等库提供了不同层级的解决方案,其中pdfplumber凭借其友好的API和详细的元素坐标信息,成为处理复杂版面(如两栏排版)的优选工具。通过精准获取文字包围盒坐标,结合版面分析算法

weixin_34297704的博客 362

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

QMC加密音频解密技术解析:从原理到批量转换实战

数字音频加密与格式转换是多媒体处理领域的基础技术,其核心原理涉及文件封装、数据混淆和密钥管理。通过逆向工程分析加密机制,可以实现音频数据的无损还原,这一过程在技术层面解决了专有格式与通用标准之间的互操作性问题。其技术价值在于赋予用户对已获授权内容的格式自主权,支持个人备份、跨设备播放和音频库标准化管理。在实际应用场景中,针对QMC等平台绑定格式的解密工具,如qmc-decoder,结合Python脚本实现批量自动化处理,能高效完成加密文件向FLAC、MP3等开放格式的转换。本文聚焦于解密逻辑拆解、环境部署和

weixin_33976072的博客 478

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

上一篇: 使用django实现前后台交互helloworld Demo
下一篇: python中多进程及multiprocessing进程池使用——批量读取excel文件
hynkoala
博客等级 码龄10年 8粉丝 26原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值