Future的内部原理

from concurrent.futures import ThreadPoolExecutor,as_completed,wait,FIRST_COMPLETED
from concurrent.futures import Future
Future未来对象:更像是task返回容器

当调用excecutor.submit(task)时,进入submit函数里会先获取一把_shutdown_lock的锁,为任务task加锁保护线程安全,

但submit更重要的功能是,在锁里生成一个Future对象f,并将生成_WorkItem(f,task,*args,**kwargs)的对象w,并将对象w放入_work_queue队列,然后调用_adjust_thread_count()方法调整线程数量,

在_WorkItem类中有一个run函数,

在submit中调用的adjust_thread_count()方法中,先判断线程数量是否小于线程池的最大数量,如果小于,就会创建一个线程,并设置守护、开始,

这个新线程执行的不是task函数,而是_worker函数,在_worker函数中会进入无限循环while True,不停地获取work_queue里的_WorkItem对象w并赋值给workitem,这里的w等同于workitem,

然后在_worker里执行w.run(),表示运行结束,就用del workitem删除这个workqueue里的对象w,再接着进入下一次循环,不停地读取运行

每一次submit(task)都会创建新线程,这个submit是不阻塞的,那么就可能产生两个线程同时运行_worker函数,就能一起读取work_queue里的任务,并在_WorkItem中完成run以及将result设置给future后删除。

_worker里执行w.run()函数后,并返回运行结果result,

再通过future.set_result(result),将result结果设置到future中

所以,这个_WorkItem的功能就是通过run方法,运行传入的函数task,并将结果设置到future中

将这新创建的线程加入到_threads中,这个_threads是set集合,但不是work_queue,要区分,_threads是存线程

work_queue是存_WorkItem的对象

在submit的最后,会返回future对象,这时的future对象,已经通过_WorkItem的run方法,将task运行后的值设置到future中了

Future中有很多方法,例如cancel\running等判断状态,但最重要的是在Future中的result()方法
result()方法是会阻塞的,它会with self._condition,这个_condition就是Condition的对象

在with self._condition中,也会调用condition.wait()方法

Future中还有很重要的set_result()方法,在set_result()方法中,也是用with _self.condition,

在with _self.condition中,也会在最后调用notify_all(),唤醒其他线程的锁
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值