python 異步 I/O


如果你想了解異步編程,那么必然會涉及出許多相關概念。

  • 堵塞/非堵塞
  • 同步/異步
  • 多進程/多線程/協程

為什么我要學習這個話,因為我想搞懂異步框架和異步接口的調用。所以,我的學習路線是這樣的:

1.python異步編程
2.python Web異步框架(tornado/sanic)
3.異步接口調用(aiohttp/httpx)

那么異步編程有什么好處?在某些場景下它可以提高性能。我們知道CPU的速度快於磁盤、網絡等IO。一旦遇到IO操作,如讀寫文件、發送網絡數據時,就需要等待IO操作完成,才能進行下一步操作。這種情況稱為同步IO。我們可以使用多線程來解決這類問題,另一種方式是通過異步。

python在3.4版本引入asyncio,到 3.5版本又加入async/await來簡化異步的使用。

先來舉個簡單的例子,假如,你和女朋友逛街。你的目的是去看新上市的華為P40手機,而你女朋友是去看新款的衣服。你們的逛街流程是這樣的。

import time


def clothes_shop():
    print("女朋友看衣服..")
    time.sleep(8)
    print("...出來了")


def huawei_shop():
    print("體驗手機..")
    time.sleep(5)
    print("...出來了")

print(time.ctime(), "開始逛街")
clothes_shop()
huawei_shop()
print(time.ctime(), "結束.")

運行結果:

Thu Apr 16 00:08:22 2020 開始逛街
女朋友看衣服..
...出來了
體驗手機..
...出來了
Thu Apr 16 00:08:35 2020 結束.

假設單位是分鍾,你們總共耗時13分鍾。

接下來,看看用異步是如何處理的:

import asyncio
import time


async def shop(delay, what):
    print(what)
    await asyncio.sleep(delay)
    print("...出來了")


async def main():
    task1 = asyncio.create_task(shop(8, '女朋友看衣服..'))
    task2 = asyncio.create_task(shop(5, '體驗手機..'))

    print(time.ctime(), "開始逛街")
    await task1
    await task2
    print(time.ctime(), "結束.")


asyncio.run(main())

通過 async/await 語法進行聲明,是編寫 asyncio 應用的推薦方式。

  • async 聲明一個函數為異步函數。
  • await 聲明處理比較耗費時的動作。
  • asyncio.run() 函數用來運行最高層級的入口點 main() 函數。
  • asyncio.create_task() 函數用來並發運行作為 asyncio 任務 的多個協程。

其實,思路非常簡單,就是你和女朋友各逛各自的,先出來的等等對方。

嚴重警告!提醒廣大直男,現實生活中千萬不要這么思考問題。一定要陪女朋友一起看衣服,還要主動去付錢。

來看看運行結果:

Thu Apr 16 00:19:19 2020 開始逛街
女朋友看衣服..
體驗手機..
...出來了
...出來了
Thu Apr 16 00:19:27 2020 結束.

假設單位是分鍾,只需要8分鍾搞定。

通過上面的例子,可以看到 task1、task2仍然有前后順序,這種前后順序的時間可以忽略不計。但是,我們也是可以使用asyncio.gather()方法並發運行任務。

#……

async def main():
    print(time.ctime(), "開始逛街")
    await asyncio.gather(
        shop(8, '女朋友看衣服..'),
        shop(5, '體驗手機..')
    )
    print(time.ctime(), "結束.")

asyncio.run(main())

運行結果同上,這里就不再貼了。

參考:https://docs.python.org/zh-cn/3/library/asyncio.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM