106、Python并发编程:深入浅出理解线程池的内部实现原理

引言

前面一篇文章中,我们介绍了通过Python中的ThreadPoolExecutor,也就是线程池更加灵活便捷地实现了Python中的多线程编程。

在Python的多线程编程中,有一个默认的原则是:"如果多线程编程不可避免,那么请尽量使用ThreadPoolExecutor来实现"。足以看到,线程池的重要性。

那么本文在对线程池的使用有一定的基础之上,稍微深入一下线程池的内部设计及实现,从而加深对线程池的理解,相信后续对多线程编程的实践能够更加得心应手。

本文的主要内容有:

1、ThreadPoolExecutor的内部构成

2、线程池的执行机制

3、Future未来对象

ThreadPoolExecutor的内部构成

我们可以结合ThreadPoolExecutor的源码来看下该对象的内部构成:

从源码中可以得出以下结论:

1、内部维持一个任务队列,也就是_work_queue,持有一个SimpleQueue对象,用于存储待执行的任务,所有提交的任务都先添加进入该队列中。

2、内部维持一个线程池,是一个set(),用于控制同时工作的线程集合。工作线程都是Thread对象,负责任务的实际执行。

3、max_workers,用于控制工作线程集合的线程最大个数。默认为CPU核数 + 1,同时限制最大不超过32。

4、通过Future对象实现线程结果及异常的跨线程传递。

线程池的执行机制

线程池的执行流程主要涉及到以下环节:

1、创建线程池:通过ThreadPoolExecutor(max_workers)创建一个线程池。

2、提交任务:通过调用submit()方法提交可调用对象(或者函数)及其参数作为待执行任务,添加至任务队列中。

3、获取工作线程:线程池中的空闲的工作线程会从任务队列中获取任务。

4、执行任务:每个工作线程会调用提交的函数并传递相应的参数。执行结果会异步地封装进Future对象中。

5、处理结果:用户可以通过Future对象获取任务的执行结果、异常信息等。可以使用result()方法等待任务执行完成并获取结果。

6、关闭线程池:任务执行完毕后,可以调用shutdown(wait=True)方法来关闭线程池,不再接受新的任务提交,并等待已提交的任务执行完成再真正关闭。

相应的执行机制,可以参考下面简化的示意图:

Future未来对象

Future对象,也叫作未来对象,用于进行线程执行结果的异步传递。它提供了一种机制来处理尚未完成的操作,允许程序在等待结果时能够有效执行其他任务。

关于Future对象的设计,需要结合源码,稍微展开介绍一下:

从初始化方法中,可以看到Future对象的实现主要涉及到几个关键组件:

1、状态管理:通过_state属性维护当前工作线程的任务执行状态,状态主要有:PENDING、RUNNING、CANCELED、CANCELED_AND_NOTIFIED、FINISHED等。

2、结果的存储:一旦任务完成,工作线程会将相应的结果设置到Future对象中,通过_result属性维持。如果工作线程执行中发生异常,也会将异常信息回写到Future对象中,通过_exception属性维持。

3、回调机制:用户可以注册回调函数,实现任务完成自动执行相应的函数的逻辑。

Future对象支持的操作主要有:

1、result(timeout=None):如果任务已经完成,则返回其结果;如果没有完成,则阻塞等待;如果超时,则抛出TimeoutError异常。

2、exception(timeout=None):如果任务执行完成并且抛出了异常,则返回该异常;否则返回None。

3、done():返回一个布尔值,标识任务是否已经执行完成。

4、cancel():取消一个任务的执行(如果可能的话),如果任务已经开始执行,则无法取消,返回False。

5、add_done_callback(fn):添加回调函数,使得任务完成时,自动调用该函数。

总的来说,正是由于Future对象的设计理念围绕着简化异步操作和提高并发编程的可用性展开。通过提供非阻塞调用、异步处理和回调机制。Future对象使得开发者可以更加方便地管理异步计算的状态和结果。它是实现高效并发执行和任务管理的重要工具,对于需要处理大量异步任务的应用程序尤为关键。

总结

本文围绕着ThreadPoolExecutor和Future对象的源码,深入介绍了相应的内部实现,以及线程池任务的处理全流程。对Future对象的设计理念和基础操作,也做了相应的展开介绍。这些都是理解线程池并发编程的核心,希望您能有所收获。

相关推荐
不去幼儿园3 分钟前
【MARL】深入理解多智能体近端策略优化(MAPPO)算法与调参
人工智能·python·算法·机器学习·强化学习
Ajiang28247353041 小时前
对于C++中stack和queue的认识以及priority_queue的模拟实现
开发语言·c++
幽兰的天空1 小时前
Python 中的模式匹配:深入了解 match 语句
开发语言·python
Theodore_10224 小时前
4 设计模式原则之接口隔离原则
java·开发语言·设计模式·java-ee·接口隔离原则·javaee
网易独家音乐人Mike Zhou4 小时前
【卡尔曼滤波】数据预测Prediction观测器的理论推导及应用 C语言、Python实现(Kalman Filter)
c语言·python·单片机·物联网·算法·嵌入式·iot
安静读书5 小时前
Python解析视频FPS(帧率)、分辨率信息
python·opencv·音视频
----云烟----6 小时前
QT中QString类的各种使用
开发语言·qt
lsx2024066 小时前
SQL SELECT 语句:基础与进阶应用
开发语言
小二·6 小时前
java基础面试题笔记(基础篇)
java·笔记·python
开心工作室_kaic7 小时前
ssm161基于web的资源共享平台的共享与开发+jsp(论文+源码)_kaic
java·开发语言·前端