首頁  >  文章  >  後端開發  >  詳解asyncio的coroutine物件與Future物件使用方法

詳解asyncio的coroutine物件與Future物件使用方法

高洛峰
高洛峰原創
2017-03-28 15:28:172877瀏覽

asyncio是Python 3.4版本引入的標準函式庫,直接內建了對非同步IO的支援。 asyncio的程式模型就是一個訊息循環。今天我們就來詳細討論下asyncio 中的coroutine 與Future對象

#">

coroutine 與Future 的關係

##看起來兩者是一樣的,因為都可以用以下的語法來非同步取得結果,

result = await future
result = await coroutine

實際上,coroutine 是生成器函數,它既可以從外部接受參數,也可以產生結果。時間內,我們可以切換到其他任務繼續執行。 。實際結果。

tasks = asyncio.gather(
  asyncio.ensure_future(func1()),
  asyncio.ensure_future(func2())
)
loop.run_until_complete(tasks)

tasks = [
  asyncio.ensure_future(func1()),
  asyncio.ensure_future(func2())
  ]
loop.run_until_complete(asyncio.wait(tasks))
ensure_future 可以將coroutine 封裝成Task。 run_until_complete 既可以接收Future 對象,也可以是coroutine 對象,

BaseEventLoop.run_until_complete(future)
Run until the Future is done.
If the argument is a coroutine object, it is wrapped by ensure_future().
Return the Future's result, or raise its exception.

Task 任務的正確

退出

方式

在asyncio 的任務循環中,如果使用CTRL-C 退出的話,即使捕獲了異常,Event Loop 中的任務會報錯,出現如下的錯誤,

Task was destroyed but it is pending!

task: wait_

for

=>

根據官方文檔,Task 物件只有在以下幾種情況,會認為是退出,

a result / exception are available, or that the future was cancelled

Task 物件的cancel 和其父類Future 略有不同。當呼叫 Task.cancel() 後,對應 coroutine 會在

事件

循環的下一輪中拋出 CancelledError 例外。使用 Future.cancelled() 並不能立即返回 True(用來表示任務結束),只有在上述異常被處理任務結束後才算是 cancelled。


故結束任務可以用

for task in asyncio.Task.all_tasks():
  task.cancel()
這種方法將所有任務找出並 cancel。

但CTRL-C 也會將事件循環停止,所以有必要重新啟動事件循環,

try:
  loop.run_until_complete(tasks)
except KeyboardInterrupt as e:
  for task in asyncio.Task.all_tasks():
    task.cancel()
  loop.run_forever() # restart loop
finally:
  loop.close()

在每個Task 中捕獲異常是必要的,如果不確定,可以使用

asyncio.gather(..., return_exceptions=True)將例外轉換為正常的結果回傳。

以上是詳解asyncio的coroutine物件與Future物件使用方法的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn