一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

腳本之家,腳本語言編程技術及教程分享平臺!
分類導航

Python|VBS|Ruby|Lua|perl|VBA|Golang|PowerShell|Erlang|autoit|Dos|bat|

服務器之家 - 腳本之家 - Python - asyncio 的 coroutine對象 與 Future對象使用指南

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

2020-09-06 12:07腳本之家 Python

asyncio是Python 3.4版本引入的標準庫,直接內置了對異步IO的支持。asyncio的編程模型就是一個消息循環。今天我們就來詳細討論下asyncio 中的 coroutine 與 Future對象

coroutineFuture 的關系

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

?
1
2
result = await future
result = await coroutine

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

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

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

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

?
1
2
3
4
5
tasks = asyncio.gather(
  asyncio.ensure_future(func1()),
  asyncio.ensure_future(func2())
)
loop.run_until_complete(tasks)

?
1
2
3
4
5
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 對象,

?
1
2
3
4
5
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。

故結束任務可以用

?
1
2
for task in asyncio.Task.all_tasks():
  task.cancel()

這種方法將所有任務找出并 cancel。

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

?
1
2
3
4
5
6
7
8
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)

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

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 毛片在线免费观看网站 | 亚洲国产成人精品激情 | 国产性tv国产精品 | 亚洲电影第1页 | 摸咪网在线影院在线观看 | 亚洲国产精品综合欧美 | 亚洲精品成人在线 | 国产成人在线播放视频 | 国产日韩欧美不卡www | 99久久一香蕉国产线看观看 | 国产在线看片网站 | 国产亚洲精品91 | 免费在线公开视频 | 国产精品日韩欧美在线 | 久久电影精品久久99久久 | 欧美va免费精品高清在线 | 国产偷窥 | 被老头肉至怀孕小说 | 亚欧美综合 | 天天视频官网天天视频在线 | 国产精品99在线观看 | 国产亚洲综合成人91精品 | 欧美一级二级片 | 好吊色永久免费视频大全 | 久久99亚洲热最新地址获取 | 男女视频在线观看 | 99视频精品国在线视频艾草 | 日韩理论片在线看免费观看 | 午夜福利合集1000在线 | 免费看日产一区二区三区 | 精品国产欧美精品v | 色中色官网 | 99香蕉网 | 吻戏辣妞范1000免费体验 | 亚洲天堂男人网 | 精品久久久久久久高清 | 交欧美| 色播艾小青国产专区在线播放 | 亚洲 日韩 国产 中文视频 | 思敏1一5集国语版免费观看 | 特黄特色一级aa毛片免费观看 |