真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

從頭造輪子:python3 asyncio之 run(2)

前言

書(shū)接上文,本文造第二個(gè)輪子,也是asyncio包里面非常常用的一個(gè)函數(shù)run

讓客戶滿意是我們工作的目標(biāo),不斷超越客戶的期望值來(lái)自于我們對(duì)這個(gè)行業(yè)的熱愛(ài)。我們立志把好的技術(shù)通過(guò)有效、簡(jiǎn)單的方式提供給客戶,將通過(guò)不懈努力成為客戶在信息化領(lǐng)域值得信任、有價(jià)值的長(zhǎng)期合作伙伴,公司提供的服務(wù)項(xiàng)目有:主機(jī)域名、虛擬主機(jī)、營(yíng)銷軟件、網(wǎng)站建設(shè)、安化網(wǎng)站維護(hù)、網(wǎng)站推廣。

一、知識(shí)準(zhǔn)備

● 相對(duì)于run_until_complete,改動(dòng)并不大,就是將入口函數(shù)重新封裝了一下,基礎(chǔ)知識(shí)主要還是run_until_complete的內(nèi)容
● asyncio.run是Python3.7之后新增的入口函數(shù)


二、環(huán)境準(zhǔn)備

組件 版本
python 3.7.7

三、run的實(shí)現(xiàn)

先來(lái)看下官方asyncio的使用方法:

|># more main.py
import asyncio
async def hello():
    print('enter hello ...')
    return 'world'

if __name__ == "__main__":
    rst = asyncio.run(hello())
    print(rst)
    
|># python3 main.py
enter hello ...
return world ...

來(lái)看下造的輪子的使用方式:

? more main.py
from wilsonasyncio import run

async def hello():
    print('enter hello ...')
    return 'return world ...'

if __name__ == "__main__":
    ret = run(hello())
    print(ret)

    
? python3 main.py
enter hello ...
return world ...

自己造的輪子也很好的運(yùn)行了,下面我們來(lái)看下輪子的代碼

四、代碼解析

輪子代碼

1)代碼組成

|># tree
.
├── eventloops.py 
├── futures.py
├── main.py
├── tasks.py
├── wilsonasyncio.py
文件 作用
eventloops.py 事件循環(huán)
futures.py futures對(duì)象
tasks.py tasks對(duì)象
wilsonasyncio.py 可調(diào)用方法集合
main.py 入口

2)代碼概覽:

eventloops.py

類/函數(shù) 方法 對(duì)象 作用 描述
Eventloop 事件循環(huán),一個(gè)線程只有運(yùn)行一個(gè)
__init__ 初始化兩個(gè)重要對(duì)象 self._readyself._stopping
self._ready 所有的待執(zhí)行任務(wù)都是從這個(gè)隊(duì)列取出來(lái),非常重要
self._stopping 事件循環(huán)完成的標(biāo)志
call_soon 調(diào)用該方法會(huì)立即將任務(wù)添加到待執(zhí)行隊(duì)列
run_once run_forever調(diào)用,從self._ready隊(duì)列里面取出任務(wù)執(zhí)行
run_forever 死循環(huán),若self._stopping則退出循環(huán)
run_until_complete 非常重要的函數(shù),任務(wù)的起點(diǎn)和終點(diǎn)(后面詳細(xì)介紹)
create_task 將傳入的函數(shù)封裝成task對(duì)象,這個(gè)操作會(huì)將task.__step添加到__ready隊(duì)列
Handle 所有的任務(wù)進(jìn)入待執(zhí)行隊(duì)列(Eventloop.call_soon)之前都會(huì)封裝成Handle對(duì)象
__init__ 初始化兩個(gè)重要對(duì)象 self._callbackself._args
self._callback 待執(zhí)行函數(shù)主體
self._args 待執(zhí)行函數(shù)參數(shù)
_run 待執(zhí)行函數(shù)執(zhí)行
get_event_loop 獲取當(dāng)前線程的事件循環(huán)
_complete_eventloop 將事件循環(huán)的_stopping標(biāo)志置位True
run 入口函數(shù) 新增

tasks.py

類/函數(shù) 方法 對(duì)象 作用 描述
Task 繼承自Future,主要用于整個(gè)協(xié)程運(yùn)行的周期
__init__ 初始化對(duì)象 self._coro ,并且call_soonself.__step加入self._ready隊(duì)列
self._coro 用戶定義的函數(shù)主體
__step Task類的核心函數(shù)
ensure_future 如果對(duì)象是一個(gè)Future對(duì)象,就返回,否則就會(huì)調(diào)用create_task返回,并且加入到_ready隊(duì)列 新增

futures.py

類/函數(shù) 方法 對(duì)象 作用 描述
Future 主要負(fù)責(zé)與用戶函數(shù)進(jìn)行交互
__init__ 初始化兩個(gè)重要對(duì)象 self._loopself._callbacks
self._loop 事件循環(huán)
self._callbacks 回調(diào)隊(duì)列,任務(wù)暫存隊(duì)列,等待時(shí)機(jī)成熟(狀態(tài)不是PENDING),就會(huì)進(jìn)入_ready隊(duì)列
add_done_callback 添加任務(wù)回調(diào)函數(shù),狀態(tài)_PENDING,就虎進(jìn)入_callbacks隊(duì)列,否則進(jìn)入_ready隊(duì)列
set_result 獲取任務(wù)執(zhí)行結(jié)果并存儲(chǔ)至_result,將狀態(tài)置位_FINISH,調(diào)用__schedule_callbacks
__schedule_callbacks 將回調(diào)函數(shù)放入_ready,等待執(zhí)行
result 獲取返回值

3)執(zhí)行過(guò)程

3.1)入口函數(shù)

main.py

async def hello():
    print('enter hello ...')
    return 'return world ...'

if __name__ == "__main__":
    ret = run(hello())
    print(ret)
  • ret = run(hello())直接調(diào)用run,參數(shù)是用戶函數(shù)hello(),我們看下run的源碼
def run(main):
    loop = get_event_loop()
    return loop.run_until_complete(main)
  • loop = get_event_loop()獲取事件循環(huán)
  • return loop.run_until_complete(main)調(diào)用run_until_complete

3.2)事件循環(huán)啟動(dòng)

    def run_until_complete(self, future):
        future = tasks.ensure_future(future, loop=self)
        future.add_done_callback(_complete_eventloop, future)
        self.run_forever()
        return future.result()
  • 與之前略有不同,future = tasks.ensure_future(future, loop=self),調(diào)用了tasks.ensure_future
def ensure_future(coro_or_future, *, loop=None):
    if isinstance(coro_or_future, Future):
        return coro_or_future
    else:
        return loop.create_task(coro_or_future)
  • 如果傳入的對(duì)象是一個(gè)普通函數(shù),那就封裝成一個(gè)task;如果已經(jīng)是一個(gè)future對(duì)象,那就直接返回。這一步的目的主要是確保傳入的對(duì)象,是一個(gè)Future類型

剩下的部分已經(jīng)沒(méi)有什么新鮮的了,和run_until_complete一樣,我們直接跳過(guò)...

3.7)執(zhí)行結(jié)果

? python3 main.py
enter hello ...
return world ...

五、流程總結(jié)

六、小結(jié)

runrun_until_complete大同小異,只不過(guò)入口函數(shù)做了一些調(diào)整,使得用戶調(diào)用更加的便利
● 本文中的代碼,參考了python 3.7.7中asyncio的源代碼,裁剪而來(lái)
● 本文中代碼:代碼



至此,本文結(jié)束
在下才疏學(xué)淺,有撒湯漏水的,請(qǐng)各位不吝賜教...
更多文章,請(qǐng)關(guān)注我:wilson.chai


分享標(biāo)題:從頭造輪子:python3 asyncio之 run(2)
文章位置:http://weahome.cn/article/dsojcog.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部