Python 異步編程 asyncio簡介及基本用法
1、asyncio是什么
async io
(異步輸入輸出)是一種編程模式,它允許程序在等待I/O操作(如文件讀寫、網(wǎng)絡(luò)請求等)完成時繼續(xù)執(zhí)行其他任務(wù)。通過這種方式,可以更有效地利用CPU資源和提高程序的響應(yīng)速度,尤其是在處理大量并發(fā)連接或長時間運(yùn)行的任務(wù)時。
asyncio
是 Python 的一個庫,用于編寫并發(fā)代碼,使用協(xié)程、任務(wù)和 Futures 來處理 I/O 密集型和高延遲操作
正常的發(fā)送請求,發(fā)送請求后會等待連接建立和服務(wù)器響應(yīng),這段時間內(nèi)cpu是空閑的,也無法切換到其他任務(wù)
asyncio允許當(dāng)執(zhí)行的任務(wù)遇到IO密集型任務(wù)時(如發(fā)送請求),cpu空閑,將cpu切換到其他任務(wù)上,做其他任務(wù),等請求建立后,可以重新切換回來,繼續(xù)進(jìn)行操作
IO密集型任務(wù)
IO 密集型任務(wù)是指那些大部分時間都花費(fèi)在輸入/輸出(I/O)操作上的任務(wù)。這些任務(wù)的特點(diǎn)是,CPU 的計(jì)算量相對較小,而等待 I/O 操作完成的時間較長。常見的 IO 密集型任務(wù)包括文件讀寫、網(wǎng)絡(luò)請求、數(shù)據(jù)庫查詢等。
例如連接網(wǎng)絡(luò),發(fā)起連接時需要cpu參與,等待連接過程是不需要cpu參與,這段時間,cpu可以空閑下來,進(jìn)行其他操作,等待到連接建立成功后需要傳輸數(shù)據(jù)了cpu再進(jìn)行操作
特征
- 長時間等待:大量時間花在等待外部設(shè)備或服務(wù)的響應(yīng)上。
- 低 CPU 占用:CPU 在等待 I/O 操作完成時處于空閑狀態(tài),因?yàn)椴恍枰M(jìn)行復(fù)雜的計(jì)算。
2、怎么用
1、基本用法
import asyncio # 定義一個異步函數(shù) async def my_coroutine(): print("開始任務(wù)") # 模擬一個耗時操作 await asyncio.sleep(1) # 等待1秒 print("任務(wù)完成") # 創(chuàng)建事件循環(huán) loop = asyncio.get_event_loop() # 運(yùn)行異步函數(shù)直到完成 loop.run_until_complete(my_coroutine()) # 關(guān)閉事件循環(huán) loop.close()
定義了一個名為my_coroutine
的協(xié)程(coroutine),它會打印一條開始任務(wù),然后暫停執(zhí)行一段時間(模擬I/O操作),最后再打印任務(wù)完成。await
關(guān)鍵字用于暫停協(xié)程的執(zhí)行,直到等待的操作完成。asyncio.sleep
是專門用來模擬異步等待的函數(shù),在實(shí)際應(yīng)用中,你可能會替換為真正的異步I/O操作,比如網(wǎng)絡(luò)請求或文件操作。
如果你想要同時運(yùn)行多個異步任務(wù),你可以使用asyncio.gather
或者asyncio.wait
等函數(shù)來管理這些任務(wù)。
實(shí)際上這樣顯示不出協(xié)程的用途
但是如果有多個任務(wù)就可以了
import asyncio # 定義一個異步函數(shù) async def my_coroutine1(): print("開始任務(wù)1") # 模擬一個耗時操作 await asyncio.sleep(1) # 等待1秒 print("任務(wù)完成1") async def my_coroutine2(): print("開始任務(wù)2") # 模擬一個耗時操作 await asyncio.sleep(1) # 等待1秒 print("任務(wù)完成2") async def main(): results = await asyncio.gather(my_coroutine1(), my_coroutine2()) print(results) if __name__ == '__main__': asyncio.run(main())
2、關(guān)鍵字 async
定義:
async
關(guān)鍵字用來聲明一個函數(shù)為異步函數(shù)(即協(xié)程)。當(dāng)一個函數(shù)被定義為異步時,它不會像普通函數(shù)那樣立即執(zhí)行其內(nèi)部代碼,而是返回一個協(xié)程對象。這個協(xié)程對象可以在事件循環(huán)中調(diào)度執(zhí)行。
async def function_name(parameters): # 協(xié)程體
使用場景:
當(dāng)你需要定義一個可能會進(jìn)行長時間等待的函數(shù)(如網(wǎng)絡(luò)請求、文件讀寫等),你可以使用async
來標(biāo)記該函數(shù),表明它是一個異步操作,并且可以通過await
來暫停它的執(zhí)行直到某些條件滿足。
await
定義:await
關(guān)鍵字只能出現(xiàn)在由async
定義的函數(shù)內(nèi)部,用于暫停當(dāng)前協(xié)程的執(zhí)行,直到所等待的另一個協(xié)程或異步操作完成。await
后面通常跟的是一個可等待對象(如另一個協(xié)程、Future
、Task
等)。
語法:
await expression
使用場景:
當(dāng)你在一個異步函數(shù)內(nèi)需要等待另一個異步操作的結(jié)果時,你可以使用await
來暫停當(dāng)前函數(shù)的執(zhí)行,讓出CPU資源給其他任務(wù),直到等待的操作完成。
asyncio.run()
:
這是運(yùn)行頂層協(xié)程的主要方式,適用于Python 3.7+版本。它會創(chuàng)建一個新的事件循環(huán)并運(yùn)行傳入的協(xié)程,直到協(xié)程完成。完成后,它會關(guān)閉事件循環(huán)并返回協(xié)程的結(jié)果。
asyncio.create_task()
:
用于在事件循環(huán)中并發(fā)啟動多個協(xié)程。它接受一個協(xié)程作為參數(shù),并返回一個Task
對象,該對象代表了正在運(yùn)行的任務(wù)。這有助于管理并發(fā)任務(wù),比如同時發(fā)起多個網(wǎng)絡(luò)請求。
import asyncio async def task1(): print("Task 1 started") await asyncio.sleep(1) print("Task 1 completed") async def task2(): print("Task 2 started") await asyncio.sleep(2) print("Task 2 completed") async def main(): # 創(chuàng)建任務(wù)但不等待它們 task_1 = asyncio.create_task(task1()) task_2 = asyncio.create_task(task2()) # 執(zhí)行其他代碼... # 等待任務(wù)完成 await task_1 await task_2 # 運(yùn)行主函數(shù) asyncio.run(main())
asyncio.gather()
:
如果想要并發(fā)地運(yùn)行多個協(xié)程并且收集所有結(jié)果,可以使用gather
。它可以接收多個協(xié)程作為參數(shù),并返回一個包含所有協(xié)程返回值的列表。
import asyncio async def task1(): print("Task 1 started") await asyncio.sleep(1) print("Task 1 completed") return "Result from Task 1" async def task2(): print("Task 2 started") await asyncio.sleep(2) print("Task 2 completed") return "Result from Task 2" async def main(): # 使用 gather 同時運(yùn)行多個任務(wù) results = await asyncio.gather(task1(), task2()) print(results) # 運(yùn)行主函數(shù) asyncio.run(main())
asyncio.wait()
可以用來等待一組協(xié)程中的任意數(shù)量完成。你可以指定不同的等待條件,如全部完成、任何一個完成等。
import asyncio async def task1(): print("Task 1 started") await asyncio.sleep(1) print("Task 1 completed") async def task2(): print("Task 2 started") await asyncio.sleep(2) print("Task 2 completed") async def main(): # 創(chuàng)建任務(wù)列表 tasks = [task1(), task2()] # 等待所有任務(wù)完成 done, pending = await asyncio.wait(tasks, return_when=asyncio.ALL_COMPLETED) for future in done: print(future.result()) # 運(yùn)行主函數(shù) asyncio.run(main())
如果你想按完成順序處理結(jié)果,而不是按照任務(wù)創(chuàng)建的順序,可以使用 asyncio.as_completed()
。它返回一個迭代器,在每個協(xié)程完成后產(chǎn)生它的Future對象。
import asyncio async def task1(): print("Task 1 started") await asyncio.sleep(1) print("Task 1 completed") return "Result from Task 1" async def task2(): print("Task 2 started") await asyncio.sleep(2) print("Task 2 completed") return "Result from Task 2" async def main(): # 創(chuàng)建任務(wù)列表 tasks = [task1(), task2()] # 按完成順序處理結(jié)果 for future in asyncio.as_completed(tasks): result = await future print(result) # 運(yùn)行主函數(shù) asyncio.run(main())
asyncio.gather()
:適合同時啟動多個任務(wù),并等待所有任務(wù)完成。asyncio.create_task()
:用于立即啟動任務(wù)并在之后等待它們完成。asyncio.wait()
:提供靈活的等待條件,例如等待所有或任一任務(wù)完成。asyncio.as_completed()
:根據(jù)任務(wù)完成的順序來處理結(jié)果。
到此這篇關(guān)于Python 異步編程 asyncio簡介及基本用法的文章就介紹到這了,更多相關(guān)Python asyncio內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
python?pycharm中使用opencv時沒有代碼自動補(bǔ)全提示的解決方案
我們在使用pycharm的時候總是很喜歡其強(qiáng)大的代碼提示功能,下面這篇文章主要給大家介紹了關(guān)于python?pycharm中使用opencv時沒有代碼自動補(bǔ)全提示的解決方案,需要的朋友可以參考下2022-09-09django orm 通過related_name反向查詢的方法
今天小編就為大家分享一篇django orm 通過related_name反向查詢的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-12-12python獲取文件真實(shí)鏈接的方法,針對于302返回碼
今天小編就為大家分享一篇python獲取文件真實(shí)鏈接的方法,針對于302返回碼,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-05-05通過Python實(shí)現(xiàn)電腦定時關(guān)機(jī)的兩種方法
這篇文章主要介紹了分別利用PyQT5和Tkinter實(shí)現(xiàn)電腦的定時關(guān)機(jī)小程序,文中的示例代碼講解詳細(xì),對我們學(xué)習(xí)Python有一定的幫助,快跟隨小編一起學(xué)習(xí)一下吧2021-12-12教你用Python腳本快速為iOS10生成圖標(biāo)和截屏
這篇文章主要介紹了教你用Python快速為iOS10生成圖標(biāo)和截屏的相關(guān)資料,非常不錯,具有參考借鑒價值,需要的朋友可以參考下2016-09-09Python3爬蟲爬取英雄聯(lián)盟高清桌面壁紙功能示例【基于Scrapy框架】
這篇文章主要介紹了Python3爬蟲爬取英雄聯(lián)盟高清桌面壁紙功能,結(jié)合實(shí)例形式分析了基于Scrapy爬蟲框架進(jìn)行圖片爬取的相關(guān)項(xiàng)目創(chuàng)建、文件結(jié)構(gòu)、功能實(shí)現(xiàn)操作技巧與注意事項(xiàng),需要的朋友可以參考下2018-12-12深入理解Python中的函數(shù)參數(shù)傳遞機(jī)制
在Python中,對于函數(shù)的參數(shù)傳遞,有兩種主要的方式:傳值和傳引用。事實(shí)上,Python的參數(shù)傳遞是一種“傳對象引用”的方式,本文呢我們將詳細(xì)介紹Python的函數(shù)參數(shù)傳遞機(jī)制,這對理解Python編程語言的底層實(shí)現(xiàn)以及優(yōu)化你的代碼都非常有幫助2023-07-07