簡體   English   中英

concurrent.futures.as_completed 是否會為已取消的期貨產生收益?

[英]Does concurrent.futures.as_completed yield for cancelled futures?

我正在使用 ThreadPoolExecutor 同時執行多個任務,這個問題是關於優雅地取消未完成的任務。 在我看來,當我取消未完成(即尚未運行)的期貨時,concurrent.futures.as_completed 永遠不會產生取消的期貨。 即使它的文檔指出“[as_completed] 在完成時產生期貨(已完成或取消的期貨)。”

例子:

import concurrent.futures
import time

def do_task(t):
    time.sleep(t)
    print('task',t,'finished')
    return t

with concurrent.futures.ThreadPoolExecutor(max_workers=3) as executor:
    future_to_t = {executor.submit(do_task, t): t for t in range(1,6)}
    for future in concurrent.futures.as_completed(future_to_t):
        print('tasks done?',[f.done() for f in future_to_t])
        t = future_to_t[future]
        if t == 1:
            executor.shutdown(wait=False, cancel_futures=True)
            print('outstanding tasks are now cancelled')
    print('all tasks done')
print('bye')

在示例中,我將 5 個任務放入管道中,並在第一個任務完成后取消它們。 由於任務 2、3 和 4 已經開始(3 個工作人員),我希望任務 5 被取消並由 as_completed 產生——但這永遠不會發生。 上面的代碼打印:

task 1 finished
tasks done? [True, False, False, False, False]
outstanding tasks are now cancelled
task 2 finished
tasks done? [True, True, False, False, True]
task 3 finished
tasks done? [True, True, True, False, True]
task 4 finished
tasks done? [True, True, True, True, True]

然后它掛起並且永遠不會all tasks done

我可以通過檢查期貨的狀態並在所有期貨完成后打破循環來解決這個問題——但這就是我對 as_completed 的期望。

我究竟做錯了什么? 有什么見解嗎? 謝謝!

跟進:

  • 如果我使用ThreadPoolExecutor.shutdown()取消期貨,他們的CANCELLED_AND_NOTIFIED會更改為CANCELLED ,但不會像concurrent.futures.as_completed()預期的那樣更改為 CANCELLED_AND_NOTIFIED 。
  • 如果我自己取消期貨, concurrent.futures.as_completed()會按預期工作。
  • 因此,作為一種解決方法,我for f in future_to_t: f.cancel()而不是executor.shutdown(wait=False, cancel_futures=True)

我遇到了同樣的問題,也想使用executor.shutdown() 如果您不介意按順序處理期貨,而不是使用as_completed()並按完成時間獲取期貨,則可以使用for循環並檢查狀態

for future in futures:
    if future.cancelled():
        pass
    result = future.result()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM