web-dev-qa-db-ja.com

Python: `concurrent.futures.ThreadPoolExecutor`のすべての先物を待ちます

concurrent.futures.ThreadPoolExecutor一連のタスク。フローを続行する前に、それらがすべて完了するまで待機します。すべての先物を保存し、それらのwaitを呼び出すことなく、どうすればそれを行うことができますか? (エグゼキューターでアクションが必要です。)

32
Ram Rachum

_Executor.shutdown_ を呼び出すだけです:

shutdown(wait=True)

Executorに、使用しているリソースをすべて解放するように通知します現在保留中のフューチャーの実行が完了したとき。シャットダウン後にExecutor.submit()およびExecutor.map()を呼び出すと、RuntimeErrorが発生します。

WaitがTrueの場合、このメソッドは保留中のすべてのフューチャーが実行を完了し、エグゼキューターに関連付けられたリソースが解放されるまで戻りません。

ただし、リストでフューチャーを追跡する場合は、 futures.wait() 関数を使用して、将来の使用のためにエグゼキューターをシャットダウンすることを回避できます。

concurrent.futures.wait(fs, timeout=None, return_when=ALL_COMPLETED)

Futureで指定されたExecutorインスタンス(異なるfsインスタンスによって作成される可能性があります)が完了するまで待ちます。セットの名前付き2タプルを返します。 doneという名前の最初のセットには、待機が完了する前に完了した(完了またはキャンセルされた)先物が含まれています。 not_doneという名前の2番目のセットには、未完了の先物が含まれています。

timeoutを指定しない場合、すべての先物が完了するまで待機することに注意してください。

代わりに futures.as_completed() を使用することもできますが、繰り返し処理する必要があります。

28
Bakuriu

バクリウの答えは正しい。少し延長するだけです。コンテキストマネージャーには__enter__および__exit__ 方法。 class ExecutorThreadPoolExecutorの基本クラス)が定義されている

class Executor(object):

    # other methods

    def shutdown(self, wait=True):
        """Clean-up the resources associated with the Executor.

        It is safe to call this method several times. Otherwise, no other
        methods can be called after this one.

        Args:
            wait: If True then shutdown will not return until all running
                futures have finished executing and the resources used by the
                executor have been reclaimed.
        """
        pass

    def __enter__(self):
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        self.shutdown(wait=True)
        return False

ThreadPoolExecutorメソッドを実際に定義するのはshutdownです

class ThreadPoolExecutor(_base.Executor):
    def shutdown(self, wait=True):
        with self._shutdown_lock:
            self._shutdown = True
            self._work_queue.put(None)
        if wait:
            for t in self._threads:
                t.join()
8
laike9m