天天看點

python協程實時輸出_Python 協程以及事件循環的問題,怎麼知道 IO 讀取結束了呢?...

最近在學習 python 的 asyncio 庫,但是有很多的疑問無法得到解答。

在《流暢的 python 》中有一個例子,計程車的離散事件仿真,它是用一個主循環排程幾個協程,利用優先級隊列來排程,但是每一次的運作時間(利用這個運作時間來模拟 IO 需要的時間)是在主循環中計算的。

關于上面那個例子可以參照這裡: https://segmentfault.com/a/1190000009798067

那麼我的第一個問題是:

我用類似上面的思想來了解 asyncio,也就是有一個隊列,主循環會不停地從隊列裡取出下一個要做的事。當遇到了 IO,我們怎麼知道 IO 的時間呢?不知道 IO 的時間我們怎麼去排定它的運作時間并把它放進隊列裡呢?

還是說這樣了解,IO 是系統調用,了解為不在我們的線程裡運作了,當系統 IO 結束了它會自動把運作完的事件加到隊列中?這樣我們就從隊列裡知道 IO 完了又開心地回到剛才進行 IO 操作的那個協程裡去了?

...可是我們是怎麼控制系統調用把完成時的事件放到隊列中呢...還必須是與 python 相容的格式...而且系統調用我們應該是無法控制的啊...

還是說其實得到系統調用傳回的結果其實很簡單...有人能寫一下代碼示意一下嗎?因為我一直不知道系統完成 IO 的通知應該通知到我們代碼的哪一行裡面。

第二個問題:

由此我引發了對其他異步的思考...比如 JavaScript 是單線程的,那麼它其實就是一個事件循環是嗎?會不斷地從隊列裡取出下一次要做的事情。比如滑鼠點選就會把點選的事件加到隊列中,然後 js 從中拿到事件,調用對應的回調函數。那麼也就是說 JavaScript 的單線程也隻能處理“響應的部分”,而滑鼠點選這個事件的捕捉是系統做的。雖然 JavaScript 的運作是單線程的,但是是需要多個線程的配合才能完成複雜的互動操作是嗎?

最後一個問題:

如果我上面說的和 python 事件循環的原理類似,那麼假設我要怎麼把系統的通知放到隊列中?比如我現在讀一個檔案,檔案讀取完畢的通知我怎麼把它包裝成符合 python 的形式放到隊列中?而且是異步,這時我們在執行别的代碼,通知會跑到哪裡去呢?比如我要把它組裝成一個 namedtuple event(name='read_down'),然後把它放到我們已經定義了的隊列中呢?有大神能幫忙寫一下嗎...

隻學了兩個月,很多了解不到位,希望大神指教。