python / python/cpython

concurrent.futures.ProcessPoolExecutor raises during shutdown

オープン
#131,598 コメント 3 件 リアクション 0 件 担当者 0 名 GitHub で見る

まだ誰も着手していません。

stdlib topic-multiprocessing type-bug
主要言語
Python
スター
77.2k
フォーク
35.9k
PR マージ指標
PR 指標を取得中

説明

Bug report

Bug description:
from concurrent.futures import ProcessPoolExecutor as Pool

def nope():
    pass

def mk_done(pool):
    def done(_fut):
        pool.shutdown(wait=True)
    return done

if __name__ == "__main__":
    pool = Pool()
    future = pool.submit(nope)
    future.add_done_callback(mk_done(pool))

ProcessPoolExecutor invokes future done callbacks from its manager thread. When one of those future callbacks invokes ProcessPoolExecutor.shutdown(), shut down fails with a RuntimeError: cannot join current thread because the implementation joins the manager thread without protecting against self-joins.

The relevant lines Lib/concurrent/futures/process.py:845-846 currently read:

if self._executor_manager_thread is not None and wait:
            self._executor_manager_thread.join()

but should probably be updated to:

t = self._executor_manager_thread
if t is not None and wait and threading.current_thread() != t:
            self._executor_manager_thread.join()

Invoking shutdown(False) avoids the problem but also makes it impossible to wait for pool completion. A more general solution would be to deprecate the wait parameter for shutdown, never waiting in that method, and add a separate method, say wait_for_shutdown, that uses a threading.Event to wake any waiting threads. Alas, correctly setting that Event is going to be a bit involved.

While I tested on 3.12, the bug is also present in 3.13 and current.

CPython versions tested on:

3.12

Operating systems tested on:

macOS

コントリビューションガイド

コントリビューションガイドを開く

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

調査の方向性

まず、提供された ProcessPoolExecutor の再現コードを実行し、次に Lib/concurrent/futures/process.py の845〜846行付近と shutdown entry point を調査します。future callback からの shutdown(wait=True) を対象とするカバレッジを追加し、self-join error が発生せずに callback が完了し、プールの完了を引き続き待機可能であることを検証します。

索引モデルが issue の本文から書いたものです。

評価

技術スタック
python
領域
backend
issue の種類
バグ
難易度
3/5
見積もり時間
1〜2日
活発さ
停滞
明瞭さ
明確に書かれている
初心者へのやさしさ
52/100

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。