状況
自作のモジュール内でcoucurrent.futures.ProcessPoolExecutor
を用いて並列処理を実装したいと考えています。
下記のコードでMAX_WORKERS = 16
として実行したところ、BrokenProcessPool
が発生しました。
Python3
1from concurrent import futures 2 3class ExampleClass: 4 def hoge(self): 5 with futures.ProcessPoolExecutor(max_workers=MAX_WORKERS) as executor: 6 results = executor.map(ExampleClass.fuga, arg) 7 8 @staticmethod 9 def fuga(arg): 10 #何かしらの処理
発生するエラー
concurrent.futures.process.BrokenProcessPool: A process in the process pool was terminated abruptly while the future was running or pending.
試したこと
自分で原因を探ったところ、OSがプロセスをkillしている可能性があるとのことで、プロセス数を減らせばエラーが発生しないと考えMAX_WORKERS = 8
とした場合にはBrokenProcessPool
は発生しませんでした。
また、公式のドキュメントを読んだところ、ProcessPoolExecutorの項で「If max_workers is None or not given, it will default to the number of processors on the machine.」とあったためMAX_WORKERS = None
としたところ、BrokenProcessPool
が発生しました。
また、concurrent.futures.ProcessPoolExecutor
で実装する前にmultiprocessing.Pool
で実装していたのですが、その際はMAX_WORKERS = 16
としてもエラーは発生しませんでした。
from multiprocessing import Pool ~~略~~ with Pool(MAX_WORKERS) as p: results = p.map(ExampleClass.fuga, arg) ~~略~~
タスクマネージャーでCPUの使用率を観測しながら実行してみたところ、CPU使用率が100%に近づいた場合にBrokenProcessPool
が発生するような印象を受けました。MAX_WORKERS = 8
とした場合のCPU使用率は60~70%ほどでした。
知りたいこと
-
BrokenProcessPool
が発生する原因、条件が知りたい。 -
multiprocessing.Pool
では実行できるのに、concurrent.futures.ProcessPoolExecutor
では実行できない理由が知りたい。 -
MAX_WORKERS
の最適な数(エラーが発生せずに安全にタスクを完了できる数)の目安が知りたい。 -
安全に並列処理を実行できる実装が知りたい。現在は
MAX_WORKERS = 8
とすれば一応動くが、他のタスクの実行中や現在のマシンよりも性能の劣るマシン上での実行などで、使用できるリソースが少ない状況でもエラーを出さずに実行したい。
また、「使用しているCPUは8コア16スレッドなので、MAX_WORKERS
を増加させるとMAX_WORKERS = 16
まではタスクが高速になる可能性がある。」という認識は正しいでしょうか。
並列処理にはあまり詳しくないため、前提知識などが抜け落ちていた場合はご教示いただければ幸いです。
よろしくおねがいします。
環境
CPU
Intel(R) Core(TM) i7-10700F CPU @ 2.90GHz
基本速度: 2.90 GHz ソケット: 1 コア: 8 論理プロセッサ数: 16 仮想化: 有効
OS
Windows10
Python ver.
Python 3.10.0
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2021/12/01 00:53