書接上文,本文造第二個輪子,也是asyncio包裡面非常常用的一個函數<code>run</code>
● 相對于<code>run_until_complete</code>,改動并不大,就是将入口函數重新封裝了一下,基礎知識主要還是<code>run_until_complete</code>的内容
● asyncio.run是Python3.7之後新增的入口函數
元件
版本
python
3.7.7
先來看下官方asyncio的使用方法:
來看下造的輪子的使用方式:
自己造的輪子也很好的運作了,下面我們來看下輪子的代碼
輪子代碼
1)代碼組成
檔案
作用
eventloops.py
事件循環
futures.py
futures對象
tasks.py
tasks對象
wilsonasyncio.py
可調用方法集合
main.py
入口
2)代碼概覽:
類/函數
方法
對象
描述
Eventloop
事件循環,一個線程隻有運作一個
<code>__init__</code>
初始化兩個重要對象 <code>self._ready</code> 與 <code>self._stopping</code>
<code>self._ready</code>
所有的待執行任務都是從這個隊列取出來,非常重要
<code>self._stopping</code>
事件循環完成的标志
<code>call_soon</code>
調用該方法會立即将任務添加到待執行隊列
<code>run_once</code>
被<code>run_forever</code>調用,從<code>self._ready</code>隊列裡面取出任務執行
<code>run_forever</code>
死循環,若<code>self._stopping</code>則退出循環
<code>run_until_complete</code>
非常重要的函數,任務的起點和終點(後面詳細介紹)
<code>create_task</code>
将傳入的函數封裝成<code>task</code>對象,這個操作會将<code>task.__step</code>添加到<code>__ready</code>隊列
<code>Handle</code>
所有的任務進入待執行隊列(<code>Eventloop.call_soon</code>)之前都會封裝成Handle對象
初始化兩個重要對象 <code>self._callback</code> 與 <code>self._args</code>
<code>self._callback</code>
待執行函數主體
<code>self._args</code>
待執行函數參數
<code>_run</code>
待執行函數執行
<code>get_event_loop</code>
擷取目前線程的事件循環
<code>_complete_eventloop</code>
将事件循環的<code>_stopping</code>标志置位True
<code>run</code>
入口函數
新增
Task
繼承自Future,主要用于整個協程運作的周期
初始化對象 <code>self._coro</code> ,并且<code>call_soon</code>将<code>self.__step</code>加入<code>self._ready</code>隊列
<code>self._coro</code>
使用者定義的函數主體
<code>__step</code>
Task類的核心函數
<code>ensure_future</code>
如果對象是一個Future對象,就傳回,否則就會調用<code>create_task</code>傳回,并且加入到<code>_ready</code>隊列
Future
主要負責與使用者函數進行互動
初始化兩個重要對象 <code>self._loop</code> 與 <code>self._callbacks</code>
<code>self._loop</code>
<code>self._callbacks</code>
回調隊列,任務暫存隊列,等待時機成熟(狀态不是<code>PENDING</code>),就會進入<code>_ready</code>隊列
<code>add_done_callback</code>
添加任務回調函數,狀态<code>_PENDING</code>,就虎進入<code>_callbacks</code>隊列,否則進入<code>_ready</code>隊列
<code>set_result</code>
擷取任務執行結果并存儲至<code>_result</code>,将狀态置位<code>_FINISH</code>,調用<code>__schedule_callbacks</code>
<code>__schedule_callbacks</code>
将回調函數放入<code>_ready</code>,等待執行
<code>result</code>
擷取傳回值
3)執行過程
3.1)入口函數
<code>ret = run(hello())</code>直接調用<code>run</code>,參數是使用者函數<code>hello()</code>,我們看下run的源碼
<code>loop = get_event_loop()</code>擷取事件循環
<code>return loop.run_until_complete(main)</code>調用<code>run_until_complete</code>
3.2)事件循環啟動
與之前略有不同,<code>future = tasks.ensure_future(future, loop=self)</code>,調用了<code>tasks.ensure_future</code>
如果傳入的對象是一個普通函數,那就封裝成一個task;如果已經是一個future對象,那就直接傳回。這一步的目的主要是確定傳入的對象,是一個Future類型
剩下的部分已經沒有什麼新鮮的了,和<code>run_until_complete</code>一樣,我們直接跳過...
3.7)執行結果

● <code>run</code>與<code>run_until_complete</code>大同小異,隻不過入口函數做了一些調整,使得使用者調用更加的便利
● 本文中的代碼,參考了python 3.7.7中asyncio的源代碼,裁剪而來
● 本文中代碼:代碼
至此,本文結束
在下才疏學淺,有撒湯漏水的,請各位不吝賜教...
更多文章,請關注我:wilson.chai
本文來自部落格園,作者:wilson排球,轉載請注明原文連結:https://www.cnblogs.com/MrVolleyball/p/15739907.html
本文版權歸作者和部落格園共有,歡迎轉載,但未經作者同意必須在文章頁面給出原文連接配接,否則保留追究法律責任的權利。