2024年Python最新一文讲透Python线程池ThreadPoolExecutor!

in main: get page 4s success



``as_completed()``方法是一个生成器,在没有任务完成的时候,会阻塞,在有某个任务完成的时候,会``yield``这个任务,就能执行for循环下面的语句,然后继续阻塞住,循环到所有的任务结束。从结果也可以看出,**先完成的任务会先通知主线程**。



### **map**


除了上面的``as_completed``方法,还可以使用``executor.map``方法,但是有一点不同。



from concurrent.futures import ThreadPoolExecutor

import time

参数times用来模拟网络请求的时间def get_html(times):

time.sleep(times)
print("get page {}s finished".format(times))
return times

executor = ThreadPoolExecutor(max_workers=2)

urls = [3, 2, 4] # 并不是真的url

for data in executor.map(get_html, urls):

print("in main: get page {}s success".format(data))

执行结果

get page 2s finished

get page 3s finished

in main: get page 3s success

in main: get page 2s success

get page 4s finished

in main: get page 4s success



使用``map``方法,无需提前使用``submit``方法,``map``方法与``python``标准库中的``map``含义相同,都是将序列中的每个元素都执行同一个函数。上面的代码就是对``urls``的每个元素都执行`get_html`函数,并分配各线程池。可以看到执行结果与上面的``as_completed``方法的结果不同,**输出顺序和****`**`**urls**`**`列表的顺序相同**,就算2s的任务先执行完成,也会先打印出3s的任务先完成,再打印2s的任务完成。



### **wait**


``wait``方法可以让主线程阻塞,直到满足设定的要求。



from concurrent.futures import ThreadPoolExecutor, wait, ALL_COMPLETED, FIRST_COMPLETEDimport time

参数times用来模拟网络请求的时间

def get_html(times):

time.sleep(times)
print("get page {}s finished".format(times))
return times

executor = ThreadPoolExecutor(max_workers=2)

urls = [3, 2, 4] # 并不是真的url

all_task = [executor.submit(get_html, (url)) for url in urls]

wait(all_task, return_when=ALL_COMPLETED)print(“main”)

执行结果

get page 2s finished

get page 3s finished

get page 4s finished

main



``wait``方法接收3个参数,等待的任务序列、超时时间以及等待条件。等待条件``return_when``默认为``ALL_COMPLETED``,表明要等待所有的任务都结束。可以看到运行结果中,确实是所有任务都完成了,主线程才打印出``main``。等待条件还可以设置为``FIRST_COMPLETED``,表示第一个任务完成就停止等待。



## 03、源码分析


`cocurrent.future`模块中的``future``的意思是*未来对象*,可以把它理解为**一个在未来完成的操作**,这是异步编程的基础 。在线程池``submit()``之后,返回的就是这个``future``对象,返回的时候任务并没有完成,但会在将来完成。也可以称之为task的返回容器,这个里面会存储task的结果和状态。那``ThreadPoolExecutor``内部是如何操作这个对象的呢?


下面简单介绍``ThreadPoolExecutor``的部分代码:


**1.init方法**



![图片](https://img-blog.csdnimg.cn/img_convert/3c8980cd28569d68093fc95bdb5e627d.jpeg)



``init``方法中主要重要的就是任务队列和线程集合,在其他方法中需要使用到。



**2.submit方法**



![图片](https://img-blog.csdnimg.cn/img_convert/4f7bb4e79da284a4e7d28acbd499cd25.jpeg)



``submit``中有两个重要的对象,``_base.Future()`和`_WorkItem()``对象,``_WorkItem()``对象负责运行任务和对`future`象进行设置,最后会将``future``对象返回,可以看到整个过程是立即返回的,没有阻塞。



**3.adjust\_thread\_count方法**



![图片](https://img-blog.csdnimg.cn/img_convert/f212910d00fe122327da5f239ac72bfa.jpeg)



这个方法的含义很好理解,主要是创建指定的线程数。但是实现上有点难以理解,比如线程执行函数中的weakref.ref,涉及到了弱引用等概念,留待以后理解。



**4.\_WorkItem对象**



![图片](https://img-blog.csdnimg.cn/img_convert/caabf77d493a1fb4f78a931fb7a41e45.jpeg)



``_WorkItem``对象的职责就是执行任务和设置结果。这里面主要复杂的还是``self.future.set_result(result)``。



**5.线程执行函数--\_worker**



![图片](https://img-blog.csdnimg.cn/img_convert/0285e73f293d9617f874d1fa5ef8776a.jpeg)



这是线程池创建线程时指定的函数入口,主要是从队列中依次取出task执行,但是函数的第一个参数还不是很明白。留待以后。



## 04、总结


* future的设计理念很棒,在线程池/进程池和携程中都存在future对象,是异步编程的核心。
* ThreadPoolExecutor 让线程的使用更加方便,减小了线程创建/销毁的资源损耗,无需考虑线程间的复杂同步,方便主线程与子线程的交互。
* 线程池的抽象程度很高,多线程和多进程的编码接口一致。



## **未完成**


* 对future模块的理解。
* weakref.ref是什么?
* 线程执行函数入口\_worker的第一个参数的意思。



**最后感谢每一个认真阅读我文章的人,看着粉丝一路的上涨和关注,礼尚往来总是要有的,虽然不是什么很值钱的东西,如果你用得到的话可以直接拿走!**


![](https://img-blog.csdnimg.cn/a096983111f247d99fb98a93ac5e6e65.png)


### 软件测试面试文档


我们学习必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有字节大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。  
  


![在这里插入图片描述](https://img-blog.csdnimg.cn/057f075a555e43b5ae94ac4c2c7f6dc1.png#pic_center)


![](https://img-blog.csdnimg.cn/b5d166f9b12b4ce9ba4ef9adcc88eaa1.png)



![在这里插入图片描述](https://img-blog.csdnimg.cn/20210511152217670.jpg?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3poaWd1aWd1,size_16,color_FFFFFF,t_70)

**感谢每一个认真阅读我文章的人,看着粉丝一路的上涨和关注,礼尚往来总是要有的:**



① 2000多本Python电子书(主流和经典的书籍应该都有了)

② Python标准库资料(最全中文版)

③ 项目源码(四五十个有趣且经典的练手项目及源码)

④ Python基础入门、爬虫、web开发、大数据分析方面的视频(适合小白学习)

⑤ Python学习路线图(告别不入流的学习)




**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**

**[需要这份系统化学习资料的朋友,可以戳这里无偿获取](https://bbs.csdn.net/topics/618317507)**

**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**
  • 7
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值