国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > Python > 正文

asyncio 的 coroutine對象 與 Future對象使用指南

2019-11-25 16:34:51
字體:
來源:轉載
供稿:網友

coroutine 與 Future 的關系

看起來兩者是一樣的,因為都可以用以下的語法來異步獲取結果,

result = await futureresult = await coroutine

實際上,coroutine 是生成器函數,它既可以從外部接受參數,也可以產生結果。使用 coroutine 的好處是,我們可以暫停一個函數,然后稍后恢復執行。比如在涉及到網路操作的情況下,能夠停下函數直到響應到來。在停下的這段時間內,我們可以切換到其他任務繼續執行。

而 Future 更像是 Javascript 中的 Promise 對象。它是一個占位符,其值會在將來被計算出來。在上述的例子中,當我們在等待網絡 IO 函數完成時,函數會給我們一個容器,Promise 會在完成時填充該容器。填充完畢后,我們可以用回調函數來獲取實際結果。

Task 對象是 Future 的子類,它將 coroutine 和 Future 聯系在一起,將 coroutine 封裝成一個 Future 對象。

一般會看到兩種任務啟動方法,

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。asyncio.gather 將一些 Future 和 coroutine 封裝成一個 Future。

asyncio.wait 則本身就是 coroutine。

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: <Task pending coro=<kill_me() done, defined at test.py:5> wait_for=<Future pending cb=[Task._wakeup()]>>

根據官方文檔,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 loopfinally:  loop.close()

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

asyncio.gather(..., return_exceptions=True)

將異常轉換為正常的結果返回。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 宣恩县| 阜康市| 宁陵县| 历史| 吉安市| 甘肃省| 虎林市| 东阳市| 丰顺县| 若尔盖县| 榆林市| 泸定县| 隆昌县| 清丰县| 翁牛特旗| 大兴区| 梁河县| 庆元县| 云安县| 隆林| 乐平市| 丹棱县| 亚东县| 迁西县| 延寿县| 五河县| 阿克陶县| 河西区| 雅安市| 崇明县| 甘德县| 五华县| 丹凤县| 临漳县| 宁德市| 湟源县| 英吉沙县| 澄江县| 娄烦县| 余姚市| 阿尔山市|