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对象的设计理念和基础操作,也做了相应的展开介绍。这些都是理解线程池并发编程的核心,希望您能有所收获。

相关推荐
冷雨夜中漫步7 小时前
Python快速入门(6)——for/if/while语句
开发语言·经验分享·笔记·python
郝学胜-神的一滴7 小时前
深入解析Python字典的继承关系:从abc模块看设计之美
网络·数据结构·python·程序人生
百锦再7 小时前
Reactive编程入门:Project Reactor 深度指南
前端·javascript·python·react.js·django·前端框架·reactjs
盐焗西兰花8 小时前
鸿蒙学习实战之路-Reader Kit修改翻页方式字体大小及行间距最佳实践
学习·华为·harmonyos
QiZhang | UESTC9 小时前
学习日记day76
学习
久邦科技9 小时前
20个免费电子书下载网站,实现电子书自由(2025持续更新)
学习
m0_736919109 小时前
C++代码风格检查工具
开发语言·c++·算法
喵手9 小时前
Python爬虫实战:旅游数据采集实战 - 携程&去哪儿酒店机票价格监控完整方案(附CSV导出 + SQLite持久化存储)!
爬虫·python·爬虫实战·零基础python爬虫教学·采集结果csv导出·旅游数据采集·携程/去哪儿酒店机票价格监控
2501_944934739 小时前
高职大数据技术专业,CDA和Python认证优先考哪个?
大数据·开发语言·python
Gain_chance9 小时前
34-学习笔记尚硅谷数仓搭建-DWS层最近一日汇总表建表语句汇总
数据仓库·hive·笔记·学习·datagrip