談談python concurrent.futures
阿新 • • 發佈:2018-12-12
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出才會阻塞。