iT邦幫忙

1

Concurrent.future Executor筆記

  • 分享至 

  • xImage
  •  

如上一篇文章筆記的Future顧名思義代表未完成的結果,像一張訂單或是掛號信,表示「這個任務已經開始執行了,這是它的結果將來會存放的地方,可以隨時來查詢它的狀態或最終的結果。」
但是還有許多特點沒有紀錄到,例如之前只記錄了兩種Executor分別使用多執行續和多行程來達成concurrent,缺少了Executor本身的筆記,所以又補了篇文章。

Executor物件

  • 提供非同步執行呼叫方法的抽象類別。因是抽象類別所以不能直接使用,要透過具體子類別也就是ThreadPoolExecutor或ProcessPoolExecutor來使用。

submit()

  • 提交單一任務到Executor,會立即返回一個Future物件,而不等待任務完成。
  • 優點是non-blocking,可以繼續做其他事情,稍後需要結果時再處理這個 Future 物件。

as_complete()

  • 本身不提交任務,接受一個包含多個 Future 物件的列表或可迭代對象,並以任務完成的順序來回傳它們。
  • 會去監聽future物件的狀態是否為完成,完成即回傳。

map()

  • 抽象化複雜性:可將 submit()、Future 物件的管理,以及結果收集等非同步流程全部包裝起來。
  • 保有 non-blocking 的優點,同時仍保持回傳結果的順序性。
  • 抽象化了以下步驟:
    • concurrent啟動:將所有任務submit到executor中,讓它們同時開始執行。
    • 按順序回傳:返回一個特殊的迭代器(iterator)。當對這個迭代器進行迭代時,會按照提交任務的順序,等待並依序回傳每個任務的結果。
    • GPT舉的例子是這樣,假設有三個任務:
      • 任務A(3秒完成)
      • 任務B(1秒完成)
      • 任務C(2秒完成)
    • 使用 as_completed(),會先拿到任務B的結果,然後是任務C,最後是任務A。但如果使用 map(),它會先等待任務A完成,然後返回其結果,接著等待任務B完成(已經因為concurrent的優勢完成了),確認返回其結果,以此類推任務C。

結論

如果要依照完成的順序性回傳結果的話使用submit()搭配as_complete(),要依照傳入的順序性回傳結果的話使用map(),兩者的程式碼依照GPT的舉例分別會像是以下:
- as_complete():
results = (future.result() for future in concurrent.futures.as_completed(futures))
- map():
results = executor.map(worker, items)


圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言