まず、プロセスプール。
同時タスクの数は、コンピュータは余裕ができるよりもはるかに大きい場合には、そのタスクのオープン過剰な数のサーバが過負荷と麻痺しないことを確実にするためには、プロセスまたはスレッドの数を制限するために考慮すべき1回限りではありません。この時、プロセスプールとスレッドプールがありました。
二つは、モジュールの導入をconcurrent.futures
concurrent.futuresモジュールは、非同期呼び出しインタフェースパッケージの高さを提供します
ThreadPoolExecutor:非同期呼び出しを提供するために、スレッドプール
ProcessPoolExecutor:プロセスプール、非同期呼び出しを提供
両方の抽象執行クラスによって定義されているのと同じインターフェースを実装
第三に、基本的な方法:
submit(fn, *args, **kwargs)
:非同期タスクの提出
map(func, *iterables, timeout=None, chunksize=1)
:ループ動作の代わりに申請
shutdown(wait=True)
:プロセス・プールの同等のpool.close()+pool.join()
操作
- 真=待って、資源回復の完了を続けた後、完了したすべてのタスクを実行するために、プールのを待ちます
- = Falseを待って、すぐに戻って、タスクの実行がプールを完了するのを待ちません
- しかし、なぜパラメータ値を待つどんなには、プログラム全体が完成し、すべてのタスクまで待機します
- マップは、シャットダウン前に提出しなければなりません
result(timeout=None)
:結果を取得します
add_done_callback(fn)
:コールバック関数
done()
:特定のスレッドが完了するかどうかを決定するために、
cancle()
:タスクをキャンセル
第四に、コード例をプールする工程--ProcessPoolExecutor
from concurrent.futures import ProcessPoolExecutor
from multiprocessing import current_process
import time
def func(i):
print(f'进程 {current_process().name} 正在执行任务 {i}')
time.sleep(1)
return i**2
if __name__ == '__main__':
pool = ProcessPoolExecutor(4) # 进程池只有4个进程
lt = []
for i in range(20): # 假设执行20个任务
future = pool.submit(func,i) # func任务要做20次,4个进程负责完成这个20个任务
# print(future.result()) # 如果没有结果就一直等待拿到结果,导致了所有任务都在串行
lt.append(future)
pool.shutdown() # 默认为True,关闭了池的入口,会等待所有的任务执行完,结束阻塞,
for fu in lt:
print(fu.result()) # 等待所有的任务都执行完了,一起把返回值打印出来
第五に、スレッドプールのコード例--ThreadPoolExecutor
from concurrent.futures import ThreadPoolExecutor
from threading import currentThread
import time
def func(i):
print(f'线程 {currentThread().name} 正在执行任务 {i}')
time.sleep(1)
return i**2
if __name__ == '__main__':
fool = ThreadPoolExecutor(4) # 线程池里只有4个线程
lt = []
for i in range(20):
futrue = fool.submit(func,i) # func任务要做20次,4个线程负责完成这20次任务
lt.append(futrue)
fool.shutdown() # 默认为True,关闭了池的入口,会等待所有的任务执行完,结束阻塞,
for fu in lt:
print(fu.result()) # 等待所有的任务都执行完了,一起把返回值打印出来
第六に、コールバック関数add_done_callback(FN)
タスクを提出するには、2つの方法:
同期:ジョブをサブミットし、あなたが他のタスクは、(戻り値を取得するために)行って実行しなければならない、次のコード行が実行する
非同期:ジョブをサブミットし、実行を待たない終わって、コードの次の行を直接実行することができます。
PS:ピースを書き込むためのプロセスおよびスレッドのコールバックメソッドの使用は、プロセスの使用とコメントしました。
from concurrent.futures import ProcessPoolExecutor,ThreadPoolExecutor
from threading import currentThread
from multiprocessing import current_process
import time
def task(i):
print(f'线程 {currentThread().name} 正在执行任务 {i}')
# print(f'进程 {current_process().name} 正在执行任务 {i}')
time.sleep(1)
return i**2
def parse(futrue):
# 处理拿到的结果
print(futrue.result())
if __name__ == '__main__':
pool = ThreadPoolExecutor(4) # 线程池里只有4个线程
# pool = ProcessPoolExecutor(4) # 进程池里只有4个进程
lt = []
for i in range(20):
futrue = pool.submit(task,i) # task任务要做20次,分别由四个进程完成这20个任务
futrue.add_done_callback(parse)
# 为当前任务绑定一个函数,在当前任务执行结束的时候会触发这个函数
# 会把futrue对象作为参数传给函数
# 这个称之为回调函数,处理完了回来就调用这个函数。
上記の例と比較すると、スレッドプール:コールバック関数の役割、彼らが実行されたすべてのタスクは、戻り値を印刷完了するまで待つ必要はありません。同時有効性を実装する、結果を印刷するために、各タスクの後に、効率が改善されています。