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,