Future 有几个重要的方法:
- .done() 返回布尔值,表示Future 是否已经执行
- .add_done_callback() 这个方法只有一个参数,类型是可调用对象,Future运行结束后会回调这个对象。
- .result() 如果 Future 运行结束后调用result(), 会返回可调用对象的结果或者抛出执行可调用对象时抛出的异常,如果是 Future 没有运行结束时调用 f.result()方法,这时会阻塞调用方所在的线程,直到有结果返回。此时result 方法还可以接收 timeout 参数,如果在指定的时间内 Future 没有运行完毕,会抛出 TimeoutError 异常。
- .as_completed() 返回一个future的生成器,该函数是阻塞的,如果future没有完成会 阻塞在当前调用的地方。
#/usr/bin/python3
#coding:utf8
from concurrent.futures import ProcessPoolExecutor,ThreadPoolExecutor,as_completed
import threading
import os,time,random
def task(n):
print('%s:%s is running' %(threading.currentThread().getName(),os.getpid()))
time.sleep(2)
return n**2
def parse_page(res): #此处的res是一个p.submit获得的一个future对象,不是结果
res=res.result() #res.result()拿到的才是对应的结果
print('result : %d' %(res))
time.sleep(2)
def main():
p=ThreadPoolExecutor() #不填则默认为cpu的个数*5
l=[]
start=time.time()
for i in range(10):
┆ obj=p.submit(task,i).add_done_callback(parse_page)
┆ l.append(obj)
p.shutdown()
print('='*30)
print(time.time()-start)
def main_as_complete():
p=ThreadPoolExecutor() #不填则默认为cpu的个数*5
l=[]
start=time.time()
for i in range(10):
┆ obj=p.submit(task,i)
┆ l.append(obj)
print("===============")
print(len(l))
for future in as_completed(l):
┆ print("++++++++++")
┆ print(future.result())
print('='*30)
print(time.time()-start)
if __name__ == '__main__':
#main()
main_as_complete()
从执行的结果来看:
as_completed()函数是阻塞的,他需要等到相应的future执行完之后才会继续执行,而如果不用as_compeleted用future的list表,在result出才会阻塞。