協程與多程序的完美結合
我們知道,協程本質上是單執行緒單程序,通過充分利用IO等待時間來實現高併發。在IO等待時間之外的程式碼,還是序列執行的。因此,如果協程非常多,多少每個協程內部的序列程式碼執行時間超過了IO請求的等待時間,那麼它的併發就會有一個上限。
舉個例子,電飯煲煮飯,洗衣機洗衣服,熱水壺燒水,他們都是啟動裝置以後就能自己執行,我們可以利用他們自己執行的時間,讓這三件事情看起來幾乎在同時進行。但如果除了這三件事情外,還有開電視,開空調,發微信……等等幾十個事情。每個事情單獨拿出來確實都只需要做個開頭,剩下的就是等,但由於做這個開頭也需要時間,因此把他們全部啟動起來也要不少時間,你的效率還是被卡住。
現在,如果有兩個人一起來做這些事情,那情況就不一樣了。一個人煮飯和燒水,另一個人開洗衣機,開電視和空調。效率進一步提升。
這就是協程與多程序的結合,每個程序裡面多個協程同時執行,充分利用CPU的每一個核心,又充分利用了IO等待時間,把CPU跑滿,把網路頻寬跑滿。強強聯合,速度更快。
有一個第三方庫aiomultiprocess,讓你能用幾行程式碼就實現多程序與協程的組合。
首先使用pip安裝:
python3 -m pip install aiomultiprocess
它的語法非常簡單:
from aiomultiprocess import Pool
async with Pool() as pool:
results = await pool.map(協程, 引數列表)
只需要3行程式碼,它就會在你CPU上每個核啟動一個程序,每個程序中不停啟動協程。
我們來寫一段實際程式碼:
import asyncio
import httpx
from aiomultiprocess import Pool
async def get(url):
async with httpx.AsyncClient() as client:
resp = await client.get(url)
return resp.text
async def main():
urls = [url1, url2, url3]
async with Pool() as pool:
async for result in pool.map(get, urls):
print(result) # 每一個URL返回的內容
if __name__ == '__main__':
asyncio.run(main())
之前我寫非同步協程文章的時候,有些人同學會問我,爬蟲的速度真的那麼重要嗎?難道不是突破反爬蟲最重要嗎?
我的回答是,不要看到用aiohttp請求網址就覺得是做爬蟲。在微服務裡面,自己請求自己的HTTP介面,也需要使用httpx或者aiohttp。在這樣的場景裡面,速度就是非常的重要,有時候就是需要做到越快越好。
以上就是本次分享的所有內容,想要了解更多歡迎前往公眾號:Python 程式設計學習圈,每日干貨分享
- 誰說程式設計師不懂浪漫,當代碼遇到文學..
- Python 為什麼沒有 void 關鍵字?
- 程式語言中分號“;”的簡明歷史
- Python 什麼情況下會生成 pyc 檔案?
- 函式和方法的裝飾器
- Python 任務自動化工具:nox 的配置與 API
- 你可能不知道的 Python 技巧
- 進一步學習 nox 教程,輕鬆掌握命令列用法
- Python 中更優雅的日誌記錄方案
- 更好用的 Python 任務自動化工具:nox 官方教程
- 如何使用 Python 操作 Git 程式碼?GitPython 入門介紹
- Python 海象運算子 (:=) 的三種用法
- 如何利用現有加密方案保護你的 Python 程式碼
- Python 為什麼要保留顯式的 self ?
- Python 浮點數的冷知識
- Python 記憶體分配時的小祕密
- 如何通過測試提升 Python 程式碼的健壯性
- 推薦5個超級實用的 Python 模組,不知道就out啦!
- Python 中幾種屬性訪問的區別
- Python 之父新發文,將替換現有解析器