官方文檔:https://pythonhosted.org/futures/
中文文檔:https://docs.python.org/zh-cn/3/library/concurrent.futures.html
什麼是concurrent.futures
concurrent.futures子產品為異步執行可調用函數提供了一個進階接口。
異步執行可以由使用ThreadPoolExecutor的線程執行,也可以使用ProcessPoolExecutor分離程序。兩者都實作相同的接口,該接口由抽象執行器類Executor定義。
Executor是一個抽象類,它提供異步執行調用的方法。不應該直接使用它,而是通過它的兩個子類:ThreadPoolExecutor和ProcessPoolExecutor。
本質上:
concurrent.futures依賴于multiprocessing和threading庫,隻不過封裝後,更友善使用這兩個庫,寫法上更簡單,也友善于多線程和多程序的代碼轉換。
線程池和程序池的用法:
from concurrent.futures import ThreadPoolExecutor,ProcessPoolExecutor
from multiprocessing import current_process
from threading import current_thread
import time,os,random
def task(i):
print(f'{current_thread().name} 在運作 任務{i}') # 這裡把具體的線程名稱标記出來
# print(f'{current_process().name} 在運作 任務{i}') # 這是程序的名稱
time.sleep(2)
return i**2
if __name__ == '__main__':
start = time.time()
pool = ThreadPoolExecutor(max_workers=5) # 這裡用多線程,如果是多程序,隻需要把這裡換成ProcessPoolExecutor(max_workers=5)
fu_list = []
for i in range(20):
future = pool.submit(task,i)
print('拿到了',i,future.result()) # 注意:這裡不print的話就是異步的,如果print,那麼需要等待task函數return,也就做不到異步了
fu_list.append(future)
pool.shutdown(wait=True) # 等待池内所有任務執行完畢
for i in fu_list:
print(i.result()) # 注意,需要.result() 方法才能得到傳回的資料
print('耗時',time.time()-start)
# 更精簡的寫法是:
# start = time.time()
# pool = ThreadPoolExecutor(5)
# fu_list = [pool.submit(task,i) for i in range(20)]
# pool.shutdown(wait=True) # 等待池内所有任務執行完畢
# result = [i.result() for i in fu_list]
# print(result)
# print('耗時',time.time()-start)