最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

python協(xié)程異步IO中asyncio的使用

 更新時間:2023年12月30日 10:53:16   作者:金色旭光  
這篇文章主要介紹了python異步編程之a(chǎn)syncio的使用,python中異步IO操作是通過asyncio來實現(xiàn)的,為了更加詳細(xì)說明asyncio,我們先從協(xié)程的最基礎(chǔ)開始講解

async await介紹

用asyncio提供的@asyncio.coroutine可以把一個生成器標(biāo)記為協(xié)程類型,然后在協(xié)程內(nèi)部用yield from 等待IO操作,讓出cpu執(zhí)行權(quán)。
然而異步的關(guān)鍵字yield 和 yield from畢竟是復(fù)用生成器關(guān)鍵字,兩者在概念上糾纏不清,所以從Python 3.5開始引入了新的語法async和await替換yield 和 yield from,讓協(xié)程的代碼更易懂。
簡單來說,可以這樣理解:

  • async 替換 @asyncio.coroutine:標(biāo)識一個函數(shù)為異步函數(shù)
  • await 替換 yield from:標(biāo)識等待IO操作,讓出CPU執(zhí)行權(quán)

async實現(xiàn)協(xié)程示例 

由于協(xié)程在各個python版本中有細(xì)微差異,本篇以python3.10為例

import asyncio
async def coro1():
    print("start coro1")
    await asyncio.sleep(2)
    print("end coro1")
async def coro2():
    print("start coro2")
    await asyncio.sleep(1)
    print("end coro2")
# 創(chuàng)建事件循環(huán)
loop = asyncio.get_event_loop()
# 創(chuàng)建任務(wù)
task1 = loop.create_task(coro1())
task2 = loop.create_task(coro2())
# 運行協(xié)程
loop.run_until_complete(asyncio.gather(task1, task2))
# 關(guān)閉事件循環(huán)
loop.close()

輸出結(jié)果:

start coro1
start coro2
end coro2
end coro1

代碼邏輯:

  • 創(chuàng)建一個事件循環(huán)
  • 將兩個異步函數(shù)coro1,coro2封裝成兩個任務(wù)task1,task2
  • 用asyncio.gather將兩個任務(wù)組合到一起,并發(fā)執(zhí)行task1,task2
  • 先執(zhí)行task1,遇到IO切換到task2
  • 執(zhí)行task2,遇到IO切換,但此時沒有等待執(zhí)行的任務(wù),cpu為空
  • task2執(zhí)行完成,task1執(zhí)行完成

從示例代碼可以看出,協(xié)程的幾個關(guān)鍵要素:

  • 事件循環(huán)
  • 協(xié)程函數(shù)定義
  • 可等待對象
  • 并發(fā)執(zhí)行

協(xié)程基本原理

組成協(xié)程最重要的因素就是事件循環(huán)和任務(wù)。

  • 任務(wù)就是一個對象,包括執(zhí)行的代碼,執(zhí)行完成、失敗等狀態(tài)以及返回結(jié)果,任務(wù)中通常會有IO切換。
  • 事件循環(huán),可以把它當(dāng)做是一個while循環(huán)。while循環(huán)在周期性的運行并執(zhí)行一些任務(wù),所有任務(wù)執(zhí)行完成會關(guān)閉循環(huán)。

偽代碼示例如下:

任務(wù)列表 = [ 任務(wù)1, 任務(wù)2, 任務(wù)3,... ]

while True:
    可執(zhí)行的任務(wù)列表,已完成的任務(wù)列表 = 去任務(wù)列表中檢查所有的任務(wù),將'可執(zhí)行'和'已完成'的任務(wù)返回
    for 就緒任務(wù) in 已準(zhǔn)備就緒的任務(wù)列表:
        執(zhí)行已就緒的任務(wù)
    for 已完成的任務(wù) in 已完成的任務(wù)列表:
        在任務(wù)列表中移除 已完成的任務(wù)

    如果 任務(wù)列表 中的任務(wù)都已完成,則終止循環(huán)

獲取和創(chuàng)建事件循環(huán):loop = asyncio.get_event_loop()

驅(qū)動事件循環(huán)運行:loop.run_until_complete(asyncio.gather(task1, task2))

事件循環(huán)過程:

事件循環(huán)中執(zhí)行任務(wù),當(dāng)執(zhí)行到某一個任務(wù)時遇到IO時,協(xié)程會讓出CPU給第二個任務(wù)執(zhí)行,第二個任務(wù)中遇到IO再次讓出CPU,直到所有任務(wù)完成。這就是協(xié)程并發(fā)性能好的一個關(guān)鍵能力:遇到IO切換任務(wù)執(zhí)行,避免了程序等待IO完成再執(zhí)行的耗時。

示例代碼的高級api實現(xiàn)

示例代碼中使用了asyncio.get_event_loop()和 loop.run_until_complete()等代碼,這些其實asyncio包的低級API,是為了展示底層原理而使用的。通常更推薦高級APIasyncio.run()實現(xiàn)協(xié)程并發(fā)。

import asyncio
async def coro1():
    print("start coro1")
    await asyncio.sleep(2)
    print("end coro1")
async def coro2():
    print("start coro2")
    await asyncio.sleep(1)
    print("end coro2")
async def main():
    task1 = asyncio.create_task(coro1())
    task2 = asyncio.create_task(coro2())
    await asyncio.gather(task1, task2)
asyncio.run(main())

run() 從功能上等價于以下低階API

loop = asyncio.get_event_loop()
task = loop.create_task(coro())
loop.run_until_complete(task)

為什么協(xié)程在IO密集時性能較好

很多人可能會疑問,多線程遇到IO也會切換,為什么協(xié)程比線程性能好呢?

簡單來是三點:

  • 協(xié)程更輕量級,切換需要恢復(fù)的上下文很少,所以比線程更快速
  • 線程切換CPU是搶占的,協(xié)程是主動讓出的,協(xié)程對CPU的使用更充分
  • 協(xié)程更輕量級,啟動線程需要的內(nèi)存資源比協(xié)程更多

以上就是python協(xié)程異步IO中asyncio的使用的詳細(xì)內(nèi)容,更多關(guān)于python asyncio的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • python筆記(2)

    python筆記(2)

    python筆記,參考上一篇文章大家繼續(xù)
    2012-10-10
  • python里反向傳播算法詳解

    python里反向傳播算法詳解

    在本篇文章了小編給大家整理的是一篇關(guān)于python里反向傳播算法詳解內(nèi)容,有興趣的朋友們可以學(xué)習(xí)下。
    2020-11-11
  • phpsir 開發(fā) 一個檢測百度關(guān)鍵字網(wǎng)站排名的python 程序

    phpsir 開發(fā) 一個檢測百度關(guān)鍵字網(wǎng)站排名的python 程序

    一個檢測百度關(guān)鍵字網(wǎng)站排名的python 程序 phpsir 開發(fā)
    2009-09-09
  • Python 中 Meta Classes詳解

    Python 中 Meta Classes詳解

    首先,在認(rèn)識metaclass之前,你需要認(rèn)識下python中的class。python中class的奇怪特性借鑒了smalltalk語言。大多數(shù)語言中,classes僅僅是用于描述怎樣創(chuàng)建一個對象的代碼端。在某種程度上說,python中的class也是這樣的。
    2016-02-02
  • python實現(xiàn)0到1之間的隨機數(shù)方式

    python實現(xiàn)0到1之間的隨機數(shù)方式

    這篇文章主要介紹了python實現(xiàn)0到1之間的隨機數(shù)方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-07-07
  • Python進(jìn)行數(shù)據(jù)提取的方法總結(jié)

    Python進(jìn)行數(shù)據(jù)提取的方法總結(jié)

    數(shù)據(jù)提取是分析師日常工作中經(jīng)常遇到的需求。如某個用戶的貸款金額,某個月或季度的利息總收入,某個特定時間段的貸款金額和筆數(shù),大于5000元的貸款數(shù)量等等。本篇文章介紹如何通過python按特定的維度或條件對數(shù)據(jù)進(jìn)行提取,完成數(shù)據(jù)提取需求。
    2016-08-08
  • PyMySQL數(shù)據(jù)庫連接與優(yōu)化方式

    PyMySQL數(shù)據(jù)庫連接與優(yōu)化方式

    本文介紹PyMySQL連接MySQL數(shù)據(jù)庫的方法,涵蓋CRUD操作、事務(wù)處理及連接池優(yōu)化,通過合理配置連接池和錯誤重試機制,提升性能并確保數(shù)據(jù)一致性
    2025-10-10
  • Django在admin后臺集成TinyMCE富文本編輯器的例子

    Django在admin后臺集成TinyMCE富文本編輯器的例子

    今天小編就為大家分享一篇Django在admin后臺集成TinyMCE富文本編輯器的例子,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-08-08
  • Python實現(xiàn)隨機爬山算法

    Python實現(xiàn)隨機爬山算法

    這篇文章主要介紹了Python實現(xiàn)隨機爬山算法的方法,幫助大家更好的利用python進(jìn)行機器學(xué)習(xí),感興趣的朋友可以了解下
    2021-01-01
  • 詳解python?pycharm與cmd中制表符不一樣

    詳解python?pycharm與cmd中制表符不一樣

    本文主要介紹了python?pycharm與cmd中制表符不一樣,這個問題通常是因為PyCharm和命令行(CMD)使用的制表符(tab)的寬度不同導(dǎo)致的,下面就來介紹一下解決方法,感興趣的可以了解一下
    2025-08-08

最新評論

广汉市| 保靖县| 临漳县| 固原市| 广南县| 肇源县| 蒙山县| 松原市| 鄂伦春自治旗| 枝江市| 西充县| 防城港市| 临海市| 永仁县| 两当县| 巫溪县| 济宁市| 海安县| 崇信县| 景德镇市| 黔西| 菏泽市| 云安县| 静安区| 屏南县| 扬中市| 阜宁县| 桓台县| 肇源县| 文化| 什邡市| 修文县| 文登市| 临高县| 大兴区| 平舆县| 迭部县| 阿巴嘎旗| 班戈县| 东丰县| 济源市|