python / python/cpython

concurrent.futures.wait() waits forever if given a cancelled future

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

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

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

説明

Bug report

concurrent.futures.wait() hangs if given a future that is already cancelled.

Steps to reproduce:

  1. Get a future that is cancellable (create lots of jobs such that the later ones cannot start yet and are therefore cancellable):
>>> import concurrent.futures
>>> pool = concurrent.futures.ThreadPoolExecutor(max_workers=1)
>>> import time
>>> for _ in range(1000): future = pool.submit(time.sleep, 1000)
  1. Cancel this future and note that it returns True meaning it has been cancelled.
>>> future.cancel()
True
  1. Now waiting on this future hangs:
>>> concurrent.futures.wait([future]) 

The expected behaviour, regardless of the value of return_when is that wait() treats cancelled futures as already completed. This is essentially how return_when=FIRST_COMPLETED and return_when=ALL_COMPLETED are documented to behave:

The function will return when any future finishes or is cancelled.

and

The function will return when all futures finish or are cancelled.

Treating a future that is cancelled prior to wait() as different to one that changes state to cancelled once waiting risks a race condition: it could change state after any possible check but before blocking. i.e. it needs to be level-triggered not edge-triggered. And indeed, it works this way for futures that are done, just not ones that are cancelled.

Your environment

  • CPython versions tested on: 3.9.7, 3.10.2
  • Operating system and architecture: Linux

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

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

はじめの一歩

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

調査の方向性

まず、concurrent.futures.wait() と、すでにキャンセルされた future を使って、提供された例を再現します。wait() のエントリポイントとキャンセルされた future の処理を調べ、その後、報告された動作のテストカバレッジを追加します。完了の条件は、文書化された return_when の値に対して、wait() がハングせずに戻ることです。

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

評価

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

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

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