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

python Threads and ThreadPoolExecutor and async python 进程和进程池 阅读详情

我们都知道,不管是Java,还是C++,还是Go,还是Python,都是有线程这个概念的。

但是我们知道,线程是不能随便创建的,就像每招一个员工一样,是有代价的,无限制招人肯定最后各种崩溃。

所以通常情况下,我们会引出线程池这个概念。

本质就是我就招了几个固定的员工,给他们派活,某一个人的活干完了再去任务中心领取新的活。

防止任务太多,一次性招太多工人,最后系统崩溃。

开心一刻

理想的多线程

实际的多线程

from concurrent.futures import ...

可能也是因为线程池这个东西用的越来越多了吧,从Python3.2+之后,就成了内置模块。

对的,直接就能使用,不需要pip进行安装什么的。

concurrent.futures下面主要有俩接口。

  • ThreadPoolExecutor 线程池。

  • ProcessPoolExecutor进程池。

这里可没有什么所谓的异步池。

个人看法:虽然异步的性能很高,但是目前除了Go以外,其他实现的都不是太好,用法上面有些怪异,当然,你们可以说我菜,我承认。

线程池

示例代码

import time
from concurrent.futures import ThreadPoolExecutor
import random


# max_workers表示工人数量,也就是线程池里面的线程数量
pool = ThreadPoolExecutor(max_workers=10)
# 任务列表
task_list = ["任务1", "任务2", "任务3", "任务4", ]




def handler(task_name):
    # 随机睡眠,模仿任务执行时间不确定性
    n = random.randrange(5)
    time.sleep(n)
    print(f"任务内容:{task_name}")




if __name__ == '__main__':
    # 遍历任务,
    for task in task_list:
        """
            交给函数处理,submit会将所有任务都提交到一个地方,不会阻塞
            然后线程池里面的每个线程会来取任务,
            比如:线程池有3个线程,但是有5个任务
            会先取走三个任务,每个线程去处理
            其中一个线程处理完自己的任务之后,会再来提交过的任务区再拿走一个任务
        """
        pool.submit(handler, task)
    print("main执行完毕")

执行结果

发现的问题

其实这个就是并发的,不要怀疑,但是你有没有发现个问题,main先执行,这说明啥?

这说明,我main跑完之后,是不管子线程的死活的。

那能不能设置一下,所有的子线程都执行完之后,main函数在执行完?

当然可以,需要一个参数即可。

pool.shutdown()

要完成上述的问题,我们需要一个参数,加上这个参数之后。

就可以让主线程等待所有子线程执行完之后,主线程再执行完。

示例代码

...
if __name__ == '__main__':
    # 遍历任务,
    for task in task_list:
        """
            交给函数处理,submit会将所有任务都提交到一个地方
            然后线程池里面的每个线程会来取任务,
            比如:线程池有3个线程,但是有5个任务
            会先取走三个任务,每个线程去处理
            其中一个线程处理完自己的任务之后,会再来提交过的任务区再拿走一个任务
        """
        pool.submit(handler, task)
    pool.shutdown()
    print("main执行完毕")

主要就是13行的pool.shutdown()。

执行结果

这次结果就是我们想要的了,hhh!!!

add_done_callback

add_done_callback可以理解为是回调函数,线程执行完之后,会自动调用指定的回调函数。

并且能拿到线程执行函数的返回值。

有什么用,我也没用过,怪我才疏学浅叭。

示例代码

import time
from concurrent.futures import ThreadPoolExecutor
import random
from concurrent.futures._base import Future


# max_workers表示工人数量,也就是线程池里面的线程数量
pool = ThreadPoolExecutor(max_workers=10)
# 任务列表
task_list = ["任务1", "任务2", "任务3", "任务4", ]




def handler(task_name):
    # 随机睡眠,模仿任务执行时间不确定性
    n = random.randrange(5)
    time.sleep(n)
    print(f"任务内容:{task_name}")
    return f"任务内容:{task_name}"




def done(res: Future):
    print("done拿到的返回值:", res.result())




if __name__ == '__main__':
    # 遍历任务,
    for task in task_list:
        futrue = pool.submit(handler, task)  # type:Future
        futrue.add_done_callback(done)
    pool.shutdown()
    print("main执行完毕")

注意:第17,27,28行代码!

执行效果

我想,可能通常用在一些善后工作叭。

多进程方式

其实通过上述几个例子,我们基本是知道怎么使用上面这个线程池了。

但是都知道Python的线程,因为GIL(全局解释器锁)的原因,是不能并发到多个物理核心上的。

所以是IO密集型的,像爬虫,读写文件,使用线程池是ok的。

但是如果说我就是野,就是头铁,非要用Python做计算型应用,像图片压缩、视频流推送,那没办法,需要使用多进程池方式。

其实通过concurrent这个接口,可以很方便的创建进程池,只需要修改两个地方。

...
# 改成导入进程池方式
from concurrent.futures import ProcessPoolExecutor
...
if __name__ == '__main__':
    ...
    # 进程池方式
    pool = ProcessPoolExecutor(max_workers=10)
    ...

只需要修改这俩地方即可,其他和上述用法一摸一样。

总结

本篇主要讲的是Python自带的线程池和进程池。

比较有特色的是,ThreadPoolExecutor,ProcessPoolExecutor的接口是一样的。

只需要修改导入的包就行。

concurrent的接口主要有pool.submit(),pool.shutdown(),futrue.add_done_callback()。

基本这几个都够自己用了。

如果在操作过程中有任何问题,欢迎在留言区吱一声。

近期热门文章

  • 你点的每个“在看”,我都认真当成了AI

用Python实现一个简单的线程池 线程池: 初始化限制该线程池最大可启动size个线程 当有新的任务进入时: 1:起初线程数为0,任务进入,创建线程。 2:已启动的线程都在运行任务,且运行线程数未达到最大线程数,则创建线程。 3:当线程中存在运行线程和阻塞线程,则将任务分配给阻塞线程。 4:当线程池中全部线程都在运行任务,则将任务放入任务队列,等待有结束线程执行或任务超时。 5:当所有任务都完成,任务队列为空,所有线程逐步退出并关闭。 当线程池关... 阅读详情

相关推荐

从零搭建AMESim与Matlab/Simulink联合仿真环境(2024版软件配置详解)

本文详细介绍了2024年最新版AMESim与Matlab/Simulink联合仿真环境的搭建与配置方法。从软件安装顺序、路径设置到编译器配置,逐步指导如何实现高效联合仿真,特别强调了版本兼容性和环境变量设置等关键细节,帮助工程师快速解决常见问题并优化仿真性能。

weixin_42538752的博客 735

python 线程池,进程池

进程池/线程池 开进程开线程都需要消耗资源,只不过两者比较的情况下线程的资源消耗的较小 所以我们要在计算机能够承受的范围内最大限度的利用计算机 在保证计算机硬件的安全情况下最大限度的利用计算机的资源 池其实是江都了程序的运行效率,但是保证了计算机永健的安全 concurrent.futures 模块 pool = ProcessPoolExecutor() 进程池 括号内可以传参数指...

Waller_的博客 1023

一文读懂GAN, pix2pix, CycleGAN和pix2pixHD

本文翻译、总结自朱俊伟的线上报告,主要讲了如何用机器学习生成图片。 来源:Games2018 Webinar 64期 :Siggraph 2018优秀博士论文报告 人员信息 主讲嘉宾 姓名:朱俊彦(Jun-Yan Zhu) 现状:麻省理工学院博士后(PostDoc at MIT),计算机科学与人工智能实验室(Computer Science and Artificial In...

gdymind的博客 6万+

python中的线程池submit应用

代码描述: _thread, threading, multiprocessing 池子, 只放制定个线程(10个线程), 线程池里面的线程越多越好? import time def timeit(f): def wrapper(*args, **kwargs): start_time = time.time() res = f(*args, **kwarg...

qq_40723809的博客 1万+

TMS320F280039 CMD文件配置避坑指南:从.map文件看懂内存分配与溢出排查

本文详细解析了TMS320F280039芯片的CMD文件配置问题,通过.map文件分析内存分配与溢出排查。文章提供了实用的诊断技巧和解决方案,帮助开发者有效应对段溢出、地址重叠和栈堆冲突等常见问题,优化DSP程序的内存管理。

weixin_29168813的博客 442

四旋翼无人机控制算法实战:从PID到MPC的路径跟踪

本文深入探讨了四旋翼无人机控制算法的演进路径,从基础的PID控制到高级的MPC算法,详细解析了各类算法的原理、实现技巧及适用场景。通过实战案例对比分析,为开发者提供从算法选型到参数调优的全方位指导,助力提升无人机飞行控制的精度与稳定性。

weixin_29090917的博客 240

python 线程池:Python的线程池之ThreadPoolExecutor

【代码】python 线程池:Python的线程池之ThreadPoolExecutor。

kunwen123的博客 546

管理信息系统(MIS)设计

一名读者可以借阅多本图书,而一本图书也可以被不同的读者借阅,所以读者与图书之间存在着多对多的借阅关系,读者与图书之间存在着多对多的联系,即m:n的联系。每一种图书属于一种图书类型,而一种图书类型可以包含很多本图书,因此可以得到图书类型与图书之间也存在着一种一对多的联系,即图书类型与图书是1:n的联系。系统应该实现以下功能:图书管理员可以维护图书信息,包括增加新书、修改图书信息、办理图书借阅登记、图书归还登记、过期图书处理、丢失图书处理及读者借阅证件信息的维护等;

m0_69718745的博客 2475

python异步编程

数据库类型 数据库名称 异步数据库 说明 key_value数据库 shelve Python常用库 - shelve // Blue Wish (isware.cn) redis tornado-redis pydblite cacheout (37条消息) Python缓存神奇库cacheout全解,优于内存的性能_攻

清风拂面 479

2025秋招LLM大模型多模态面试题(八)- langchain完整面试题

1. **什么是 LangChain** 2. **LangChain 包含哪些核心模块** - 模型输入/输出(Model I/O) - 组件管理 - 数据处理 - 链式组合 - 记忆与上下文管理 - 外部集成 3. **一些核心概念** 4. **什么是 LangChain Agent?** 5. **什么是 LangChain model?** 6. **LangChain 包含哪些特点?** 7. **LangChain 如何使用?** - LangChai

weixin_41496173的博客 2192

【光斑定位】空间激光通信、光斑定位、CCD、光斑定位——13000字

0.完整源码获得方式 订阅MATLAB/FPGA教程,免费获得教程案例以及任意2份完整源码 ----------------------------------------------------------------- 空间激光通信是指以光波作为载波进行数据传输的一种通信方式。目前,空间激光通信己成为人们关注的焦点。在空间激光通信系统中,光斑定位是是一项关键技术。 本论文首先对国内外空间激光通信系统的研究现状进行了阐述,论述了空间激光通信的理论只是,并对CCD成像原理,...

FPGA/MATLAB学习教程/源码/项目合作开发 1290

盘点3个可以操作JavaScript的Python库

点击上方“Python爬虫与数据挖掘”,进行关注回复“书籍”即可获赠Python从入门到进阶共10本电子书今日鸡汤人生若只如初见,何事秋风悲画扇。前言我们都知道Python可以很轻松的实现...

pdcfighting的博客 400

博途PLC模糊PID控制(量化因子和比例因子)

参数"量化因子和比例因子",都是为了对清晰值进行比例变换而设置的,其作用是使变量按一定比例进行放大或缩小,以便和我们的模糊论域相匹配完成一一映射。这种变换对整个系统的工作性能也是有影响的。(其实相当于额外引入了比例作用,所以说模糊PID的调节是个系统工程)。限于本人能力,文中难免出现错误和不足,欢迎大家批评和指正。博途PLC的模糊PID控制完整算法可以参看下面这篇文章博途PLC模糊PID控制详解(SCL完整源代码+参数)_RXXW_Dor的博客-优快云博客。......

RXXW_Dor的博客 5269

手把手教你用Python网络爬虫获取头条所有好友信息

点击上方“Python爬虫与数据挖掘”,进行关注回复“书籍”即可获赠Python从入门到进阶共10本电子书今日鸡汤桃李春风一杯酒,江湖夜雨十年灯。前言大家好,我是黄伟。今日头条我发觉做的挺...

pdcfighting的博客 580

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

转载:浅析Python中的多进程与多线程的使用

在批评Python的讨论中,常常说起Python多线程是多么的难用。还有人对 global interpreter lock(也被亲切的称为“GIL”)指指点点,说它阻碍了Python的多线程程序同时运行。因此,如果你是从其他语言(比如C++或Java)转过来的话,Python线程模块并不会像你想象的那样去运行。必须要说明的是,我们还是可以用Python写出能并发或并行的代码,并且能带来性能的显著...

weixin_30905981的博客 83

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

线程池的使用

目标 【理解】线程池基本概念 【理解】线程池工作原理 【掌握】自定义线程池 【应用】java内置线程池 【应用】使用java内置线程池完成综合案例 线程池 线程池基础 线程池使用 线程池综合案例 学员练习 线程池总结 概念介绍 什么是线程池 为什么使用线程池 线程池有哪些优势 什么是线程池 线程池其实就是一种多线程处理形式,处理过程中可以将任务添加到队列中,然后在创建线程后自动启动这些任务。这里的线程就是我们前面学过的线程,这里的任务就是我们前面学过的实现了Runnable或Callable接口的实例对象;

孙海颜 831

lwip-2.0.3

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

线程池的submit和execute方法区别

线程池中的execute方法大家都不陌生,即开启线程执行池中的任务。还有一个方法submit也可以做到,它的功能是提交指定的任务去执行并且返回Future对象,即执行的结果。下面简要介绍一下两者的三个区别: 1、接收的参数不一样 public class MainTest { public static void main(String[] args) throws Exception { ExecutorService pool = Executors.newFixedT

花&败 1514

线程池笔记

→ submit方法 池子会自动地帮我们创建对象,任务执行完毕,也会自动把线程对象归还池子。核心元素七:当排队人数过多,超出顾客请下次再来(拒绝服务)→ 要执行的任务过多时的解决方案。2.当有任务需要执行时,才会创建线程对象,当任务执行完毕,线程对象归还给池子。核心元素四:临时员工空闲多长时间被辞退(单位)→空闲时间(单位)参数二:最大线程数 → 不能小于等于0,最大数量>=核心线程数量。核心元素三:临时员工空闲多长时间被辞退(值)→ 空闲时间(值)核心元素二:餐厅最大员工数 → 线程池中最大线程的数量。

qq_33449977的博客 470

python函数参数中的/和*

作者:乘风 链接:https://www.zhihu.com/question/287097169/answer/453193254 来源:知乎 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 在python3.8之后函数参数中允许出现/和*号,/用来指明某些函数形参必须使用位置参数而非关键字参数的形式,*出现在函数参数中第一种含义可以表示为可变参数,一般写作*args;对于单独出现在参数中的*参数,则表示,*后面的参数必须为关键字参数的形式,接下来详细说下该用法: 1 /参数的用法

Ema1997的博客 1003

python中级第二十课--创建并行任务(小白piao分享)

请注意:在之前的章节中已经涉及了关于并行&并发的概念,请各位移步python中级第十七课查看相关概念,这里不再赘述。 目的:利用多个CPU同时工作提高执行效率 方法:      这里我们借鉴了一个很好的例子,关于解析阿帕奇web服务器中日志的例子。通过脚本实现获取访问过robot.txt文件的主机数据。 #log格式类似于如下; ''' 122.12...

weixin_43520503的博客 291

线程池

/** 线程池: 1.创建线程池(ExecutorService) 真正的线程池接口:java.util.concurrent.ExecutorService. Runnable形式。 2.创建线程池的步骤: 1.创建一个线程池。 2.通过Executors下的一个静态方法newFixedThreadPool(int nums),创建一个固定...

linggle的博客 353

多线程与高并发-线程入门(一)

系列文章目录 多线程与高并发-(一) 文章目录系列文章目录前言一 多线程1.1 定义1.2 特点1.3 状态1.4 创建方式二 线程池2.1三 synchronized1、为什么需要使用多线程? 前言 多线程和高并发在大厂面试和在大流量的系统是常涉及到的。老铁们要是不会这个,要想拿高薪,那是没戏的,再说吹牛逼也是需要资本的。 一 多线程 多线程的就是不同的执行路径。 1.1 定义 多线程是这样一种机制,它允许在程序中并发执行多个指令流,每个指令流都称为一个线程,彼此间互相独立。 1.2 特点 在j

hellothejava的博客 377

Python笔记 之 简单并发任务(线程/进程池)

线程池的基类是 concurrent.futures 模块中的ThreadPoolExecutor 和 ProcessPoolExecutor两个子类,其中 ThreadPoolExecutor 用于创建线程池,而 ProcessPoolExecutor 用于创建进程池。4,调用 ThreadPoolExecutor 对象的 shutdown(wait = True) 方法来关闭线程池。3,调用 ThreadPoolExecutor 对象的 submit() 方法来提交线程任务;

一起种梧桐吧的博客 1438

python -线程池

1.线程池-submit python3.2版本之后才有的; from concurrent.futures import ThreadPoolExecutor def job(num): # 需要执行的任务 print("这是一个%s任务" %(num)) return "执行结果:%s" %(num) if __name__ == '__main__': ...

淋巴cell学习py之路 1431
上一篇: 0代码就能做Python数据分析,这个Jupyter插件,用起来就像Excel一样简单
下一篇: 爬取了知乎2.2亿阅读量 "有漂亮女朋友是什么体验",结果发现...
菜鸟学Python
博客等级 码龄9年 8044粉丝 571原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值