衡阳派盒市场营销有限公司

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

Python異步IO的核心知識,你掌握了嗎?

馬哥Linux運維 ? 來源:lq ? 2018-12-04 17:09 ? 次閱讀

Python 的 asyncio 類似于 C++ 的 Boost.Asio。

異步 IO,就是你發(fā)起一個 IO 操作,不用等它結束,可以繼續(xù)做其他事情,當它結束時,你會得到通知。

Asyncio 是并發(fā)(concurrency)的一種方式。對 Python 來說,并發(fā)還可以通過線程(threading)和多進程(multiprocessing)來實現(xiàn)。

Asyncio 并不能帶來真正的并行(parallelism)。當然,因為 GIL(全局解釋器鎖)的存在,Python 的多線程也不能帶來真正的并行。

可交給 asyncio 執(zhí)行的任務,稱為協(xié)程(coroutine)。一個協(xié)程可以放棄執(zhí)行,把機會讓給其它協(xié)程(即 yield from 或 await)。

定義協(xié)程

協(xié)程的定義,需要使用 async def 語句。

do_some_work 便是一個協(xié)程。

準確來說,do_some_work 是一個協(xié)程函數(shù),可以通過 asyncio.iscoroutinefunction 來驗證:

這個協(xié)程什么都沒做,我們讓它睡眠幾秒,以模擬實際的工作量 :

在解釋 await 之前,有必要說明一下協(xié)程可以做哪些事。協(xié)程可以:

asyncio.sleep 也是一個協(xié)程,所以 await asyncio.sleep(x) 就是等待另一個協(xié)程??蓞⒁?asyncio.sleep 的文檔:

運行協(xié)程

調用協(xié)程函數(shù),協(xié)程并不會開始運行,只是返回一個協(xié)程對象,可以通過 asyncio.iscoroutine 來驗證:

此處還會引發(fā)一條警告:

要讓這個協(xié)程對象運行的話,有兩種方式:

簡單來說,只有 loop 運行了,協(xié)程才可能運行。

下面先拿到當前線程缺省的 loop ,然后把協(xié)程對象交給 loop.run_until_complete,協(xié)程對象隨后會在 loop 里得到運行。

run_until_complete 是一個阻塞(blocking)調用,直到協(xié)程運行結束,它才返回。這一點從函數(shù)名不難看出。

run_until_complete 的參數(shù)是一個 future,但是我們這里傳給它的卻是協(xié)程對象,之所以能這樣,是因為它在內部做了檢查,通過 ensure_future 函數(shù)把協(xié)程對象包裝(wrap)成了 future。所以,我們可以寫得更明顯一些:

完整代碼:

運行結果:

回調

假如協(xié)程是一個 IO 的讀操作,等它讀完數(shù)據(jù)后,我們希望得到通知,以便下一步數(shù)據(jù)的處理。這一需求可以通過往 future 添加回調來實現(xiàn)。

多個協(xié)程

實際項目中,往往有多個協(xié)程,同時在一個 loop 里運行。為了把多個協(xié)程交給 loop,需要借助 asyncio.gather 函數(shù)。

或者先把協(xié)程存在列表里:

運行結果:

這兩個協(xié)程是并發(fā)運行的,所以等待的時間不是 1 + 3 = 4 秒,而是以耗時較長的那個協(xié)程為準。

參考函數(shù) gather 的文檔:

發(fā)現(xiàn)也可以傳 futures 給它:

gather 起聚合的作用,把多個 futures 包裝成單個 future,因為 loop.run_until_complete 只接受單個 future。

run_until_complete 和 run_forever

我們一直通過 run_until_complete 來運行 loop ,等到 future 完成,run_until_complete 也就返回了。

輸出:

現(xiàn)在改用 run_forever:

輸出:

三秒鐘過后,future 結束,但是程序并不會退出。run_forever 會一直運行,直到 stop 被調用,但是你不能像下面這樣調 stop:

run_forever 不返回,stop 永遠也不會被調用。所以,只能在協(xié)程中調 stop:

這樣并非沒有問題,假如有多個協(xié)程在 loop 里運行:

第二個協(xié)程沒結束,loop 就停止了——被先結束的那個協(xié)程給停掉的。

要解決這個問題,可以用 gather 把多個協(xié)程合并成一個 future,并添加回調,然后在回調里再去停止 loop。

其實這基本上就是 run_until_complete 的實現(xiàn)了,run_until_complete 在內部也是調用 run_forever。

Close Loop?

以上示例都沒有調用 loop.close,好像也沒有什么問題。所以到底要不要調 loop.close 呢?

簡單來說,loop 只要不關閉,就還可以再運行。:

但是如果關閉了,就不能再運行了:

建議調用 loop.close,以徹底清理 loop 對象防止誤用。

gather vs. wait

asyncio.gather 和 asyncio.wait 功能相似。

具體差別可請參見 StackOverflow 的討論:Asyncio.gather vs asyncio.wait。

Timer

C++ Boost.Asio 提供了 IO 對象 timer,但是 Python 并沒有原生支持 timer,不過可以用 asyncio.sleep 模擬。

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權轉載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • python
    +關注

    關注

    56

    文章

    4807

    瀏覽量

    85040
  • 線程
    +關注

    關注

    0

    文章

    505

    瀏覽量

    19758

原文標題:Python 的異步 IO:Asyncio 簡介

文章出處:【微信號:magedu-Linux,微信公眾號:馬哥Linux運維】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    [8.1]--C++核心知識掌握了嗎

    人工智能
    jf_90840116
    發(fā)布于 :2023年02月20日 22:11:34

    異步IO是什么

    python 異步ioAsync IO is a concurrent programming design that has received dedicated support
    發(fā)表于 09-06 07:26

    數(shù)據(jù)結構預算法核心知識點總結概述

    數(shù)據(jù)結構預算法核心知識點總結概述最近有看一些大佬的專欄,受益匪淺。深刻的覺察到我們要想成為一個偉大的程序員,或者說小一點,成為一個厲害的程序員,基礎知識核心競爭力也是我們不斷向上提升個人能力的基石
    發(fā)表于 12-21 08:00

    嵌入式開發(fā)中會用到哪些核心知識

    、什么是嵌入式、嵌入式系統(tǒng)的技術特征、三次信息化浪潮、嵌入式技術的主要發(fā)展方向和主流產品。2、什么人適合學習嵌入式本節(jié)主要講述嵌入式開發(fā)中會用到哪些核心知識,需要哪些核心技能,嵌入式開發(fā)和Android應用、微信定制開發(fā)等純應用層開發(fā)的不同之處,最后分析了哪些人適合學習嵌
    發(fā)表于 12-24 07:39

    IIC的核心知識點匯總,絕對實用

    IIC的核心知識點匯總,絕對實用
    發(fā)表于 01-24 06:14

    FPGA核心知識詳解(1):FPGA入門必備

    電子發(fā)燒友網(wǎng)核心提示 :對初級FPGA工程師而言,必須掌握FPGA相關基礎知識、精通硬件描述語言、熟練數(shù)字電路設計、加強工程項目的實踐。應廣大初級FPGA工程師/FPGA愛好者之需,電子
    發(fā)表于 11-09 13:55 ?8118次閱讀

    縱觀全球頂級新材料實驗室,知識都抓住了嗎

    縱觀全球頂級新材料實驗室,知識都抓住了嗎
    的頭像 發(fā)表于 04-22 17:36 ?3110次閱讀
    縱觀全球頂級新材料實驗室,<b class='flag-5'>知識</b>點<b class='flag-5'>你</b>都抓住<b class='flag-5'>了嗎</b>?

    曾經分不清的RAM知識 現(xiàn)在搞明白了嗎?

    曾經分不清的RAM知識現(xiàn)在搞明白了嗎?
    的頭像 發(fā)表于 02-25 15:33 ?3273次閱讀

    淺析同步與異步Python的區(qū)別與概述

    是否聽到人們說過,異步Python代碼比普通(或同步)Python代碼更快?果真是那樣嗎?
    的頭像 發(fā)表于 04-25 13:53 ?2250次閱讀
    淺析同步與<b class='flag-5'>異步</b><b class='flag-5'>Python</b>的區(qū)別與概述

    信號驅動IO異步IO的區(qū)別

    一. 談信號驅動IO (對比異步IO來看) 信號驅動IO 對比 異步 IO進行理解 信號驅動
    的頭像 發(fā)表于 11-08 15:32 ?1135次閱讀
    信號驅動<b class='flag-5'>IO</b>與<b class='flag-5'>異步</b><b class='flag-5'>IO</b>的區(qū)別

    linux異步io框架iouring應用

    Linux內核5.1支持了新的異步IO框架iouring,由Block IO大神也即Fio作者Jens Axboe開發(fā),意在提供一套公用的網(wǎng)絡和磁盤異步
    的頭像 發(fā)表于 11-08 15:39 ?733次閱讀
    linux<b class='flag-5'>異步</b><b class='flag-5'>io</b>框架iouring應用

    異步IO框架iouring介紹

    前言 Linux內核5.1支持了新的異步IO框架iouring,由Block IO大神也即Fio作者Jens Axboe開發(fā),意在提供一套公用的網(wǎng)絡和磁盤異步
    的頭像 發(fā)表于 11-09 09:30 ?2616次閱讀
    <b class='flag-5'>異步</b><b class='flag-5'>IO</b>框架iouring介紹

    電源時序控制的正確方法,掌握了嗎

    電源時序控制的正確方法,掌握了嗎
    的頭像 發(fā)表于 12-15 09:27 ?1500次閱讀
    電源時序控制的正確方法,<b class='flag-5'>你</b><b class='flag-5'>掌握</b><b class='flag-5'>了嗎</b>?

    淺談初級電工必備知識

    對于初學電工的朋友來說,掌握一些基礎且實用的知識點是非常重要的。本文旨在分享初級電工應該掌握核心知識,幫助新手電工更好地入門和提升技能。
    的頭像 發(fā)表于 12-26 10:44 ?1273次閱讀

    掌握EMC核心知識——7天倒計時!

    賽盛技術第九期“EMC實戰(zhàn)特訓營“開課倒計時7天”!本期課特訓營將于12月18日正式開課,課程涵蓋電磁兼容(EMC)領域的核心知識。四位資深講師主講,團隊經驗累計超過70年,并結合賽盛技術公司19年
    的頭像 發(fā)表于 12-11 09:40 ?222次閱讀
    <b class='flag-5'>掌握</b>EMC<b class='flag-5'>核心知識</b>——7天倒計時!
    百家乐大赌场娱乐网规则| 大发888真人存款| 澳门1百家乐官网网| 百家乐获胜秘决| 娱乐城送18| 澳门百家乐赢技巧| 赌博投注| 做生意店内格局| 最好的网上真人赌博| 最好的百家乐游戏平台1| 百家乐官网桌| 星期八百家乐的玩法技巧和规则| 百家乐官网微笑投注| 大发888推广合作| 吕梁市| 女优百家乐的玩法技巧和规则| 百家乐官网赚钱方| 赌场风云国语| 大家赢百家乐投注| 百家乐官网博娱乐网| 新葡京国际娱乐城| 百家乐| 百家乐官网怎么看大小| 永善县| 百家乐赢输| 金域百家乐官网的玩法技巧和规则 | 平潭县| 大发888娱乐平台| 百家乐桌德州扑克桌| 在线百家乐官网| 大发888-大发娱乐城下载| 百家乐官网蓝盾有赢钱的吗| 蒲城县| 大发888的促销代码| 百家乐api| 百家乐官网投注| 赌场百家乐官网赢钱| 网上真钱娱乐平台| 全讯网社区| 百家乐英皇娱乐城| 24山认龙立向|