Python異步完全指南實(shí)例小結(jié)
Python中并行處理多個(gè)任務(wù)主要是靠:
- thread 線程
- process 進(jìn)程
- asyncio 非同步
process
將一個(gè)py 腳本放入到內(nèi)存中,程序就變成了 一個(gè)process
process 是程序運(yùn)行的實(shí)例,process 有自己的內(nèi)存,通信;不同的process之間彼此獨(dú)立
process 通常分為二種
- I/O密集型,cpu使用率較低,大量時(shí)間在等待網(wǎng)絡(luò),用戶輸入輸出
- CPU 密集型,cpu使用率較高,在大量計(jì)算,數(shù)據(jù)分析,視頻編碼等
Thread 線程
線程是Process的最小單位,每個(gè)Process 至少有一個(gè)線程(主線程);線程在同一個(gè)process內(nèi)共享資源,一個(gè)線程操作不當(dāng),會(huì)導(dǎo)致整個(gè)process 崩潰。
CPU 執(zhí)行process / thread的機(jī)制
CPU 一次只能執(zhí)行一個(gè)任務(wù),為了處理多個(gè)任務(wù),搶占式切換任務(wù)。
搶占式切換:process保留當(dāng)前狀態(tài),開辟新的內(nèi)存空間,增加消耗,在同一個(gè)process里,thread 共享空間,所以開銷更小。
對(duì)于多核CPU ,每個(gè)核心都能處理不同的進(jìn)程。節(jié)省了大量的切換開銷。
PYTHON GIL鎖機(jī)制
在同一個(gè)process內(nèi),GIL是一種鎖,允許任何時(shí)候只有一個(gè)線程控制 Python 解釋器。在I/O 等待場(chǎng)景,會(huì)釋放GIT鎖。
GIL 的存在是為了解決競(jìng)態(tài)問題,防止多個(gè)線程彼此大家。
asyncio 異步
asyncio 使用單一線程來處理多個(gè)任務(wù),避免了大量上下文切換帶來的開銷
- Coroutines 把普通函數(shù)定義為協(xié)程函數(shù) 代表該函數(shù)可以暫停/恢復(fù)
- Event loop 事件循環(huán),負(fù)責(zé)管理執(zhí)行Coroutines
- Tasks 協(xié)程具體的對(duì)象 通過asyncio.create_task()調(diào)度
- await 暫停協(xié)程的執(zhí)行
協(xié)程創(chuàng)建之后,不會(huì)自動(dòng)調(diào)用。asyncio.run()來運(yùn)行
適合 需要大量等待的小任務(wù)場(chǎng)景
asyncio.create_task()
讓函數(shù)立即進(jìn)入隊(duì)列(不是立即執(zhí)行,等待其他函數(shù)交出控制權(quán))create_task() 解除等待關(guān)系,把協(xié)程交給事件循環(huán)管理;只要存在 await 的讓出點(diǎn),多個(gè)任務(wù)就可以交叉推進(jìn)
await a() await b() # 交叉 ta = create_task(a()) tb = create_task(b()) await ta await tb
asyncio.to_thread
asyncio.to_thread 讓同步阻塞代碼在另一個(gè)線程運(yùn)行,從而保證事件循環(huán)線程不被阻塞。
async def main():
print("start")
asyncio.create_task(
asyncio.to_thread(fetch_data)
)
print("end")| 寫法 | 函數(shù)何時(shí)執(zhí)行 | 當(dāng)前協(xié)程是否繼續(xù) |
|---|---|---|
await to_thread() | 立即(在線程) | 否(等結(jié)果) |
create_task(to_thread()) | 立即(在線程) | 是 |
檢測(cè)判斷
你在 async 函數(shù)里,要調(diào)用一個(gè)函數(shù) F
│
├─ F 是 async 協(xié)程函數(shù)?
│ │
│ ├─ 是
│ │ │
│ │ ├─ 需要等 F 的結(jié)果?
│ │ │ ├─ 是 → await F()
│ │ │ └─ 否 → create_task(F())
│ │ │
│ │ └─(結(jié)束)
│ │
│ └─ 否(F 是同步阻塞函數(shù))
│ │
│ ├─ 需要等 F 的結(jié)果?
│ │ ├─ 是 → await asyncio.to_thread(F)
│ │ └─ 否 → create_task(asyncio.to_thread(F))
│ │
│ └─(結(jié)束)
到此這篇關(guān)于Python異步完全指南的文章就介紹到這了,更多相關(guān)Python異步完全指南內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Python結(jié)合多線程與協(xié)程實(shí)現(xiàn)高效異步請(qǐng)求處理
- Python解決多線程運(yùn)行異步代碼報(bào)錯(cuò)"There?is?no?current?event?loop"
- Python多線程與異步處理在HTTP請(qǐng)求中的應(yīng)用方式
- Python異步爬蟲多線程與線程池示例詳解
- Python logging模塊異步線程寫日志實(shí)現(xiàn)過程解析
- 淺談PyQt5中異步刷新UI和Python多線程總結(jié)
- Python實(shí)現(xiàn)可設(shè)置持續(xù)運(yùn)行時(shí)間、線程數(shù)及時(shí)間間隔的多線程異步post請(qǐng)求功能
- python并發(fā)編程之多進(jìn)程、多線程、異步和協(xié)程詳解
- Python多線程、異步+多進(jìn)程爬蟲實(shí)現(xiàn)代碼
相關(guān)文章
Python+matplotlib實(shí)現(xiàn)堆疊圖的繪制
Matplotlib作為Python的2D繪圖庫(kù),它以各種硬拷貝格式和跨平臺(tái)的交互式環(huán)境生成出版質(zhì)量級(jí)別的圖形。本文將利用Matplotlib庫(kù)繪制堆疊圖,感興趣的可以了解一下2022-03-03
利用Python實(shí)現(xiàn)簡(jiǎn)單的相似圖片搜索的教程
這篇文章主要介紹了利用Python實(shí)現(xiàn)簡(jiǎn)單的相似圖片搜索的教程,文中的示例主要在一個(gè)圖片指紋數(shù)據(jù)庫(kù)中實(shí)現(xiàn),需要的朋友可以參考下2015-04-04
Python讀取Pickle文件信息并計(jì)算與當(dāng)前時(shí)間間隔的方法分析
這篇文章主要介紹了Python讀取Pickle文件信息并計(jì)算與當(dāng)前時(shí)間間隔的方法,涉及Python基于pickle模塊操作文件屬性相關(guān)實(shí)現(xiàn)技巧,需要的朋友可以參考下2019-01-01
python動(dòng)態(tài)網(wǎng)頁(yè)批量爬取
這篇文章主要介紹了python動(dòng)態(tài)網(wǎng)頁(yè)批量爬取的方法,主要針對(duì)四六級(jí)成績(jī)批量爬取,感興趣的小伙伴們可以參考一下2016-02-02
基于Django實(shí)現(xiàn)日志記錄報(bào)錯(cuò)信息
這篇文章主要介紹了基于Django實(shí)現(xiàn)日志記錄報(bào)錯(cuò)信息,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-12-12
Pandas如何對(duì)Categorical類型字段數(shù)據(jù)統(tǒng)計(jì)實(shí)戰(zhàn)案例
這篇文章主要介紹了Pandas如何對(duì)Categorical類型字段數(shù)據(jù)統(tǒng)計(jì)實(shí)戰(zhàn)案例,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下2022-08-08

