Python多進(jìn)程、多線程、協(xié)程典型示例解析(最新推薦)
一、multiprocessing(多進(jìn)程)
1. 模塊簡介
- 作用:創(chuàng)建多個(gè)獨(dú)立運(yùn)行的進(jìn)程(每個(gè)進(jìn)程有獨(dú)立內(nèi)存空間)
- 適用場景:數(shù)學(xué)計(jì)算、圖像處理等CPU密集型任務(wù)
- 核心原理:繞過Python的GIL鎖,真正利用多核CPU
2. 案例詳解:并行計(jì)算平方和
import multiprocessing import time # 計(jì)算平方的任務(wù)函數(shù) def calculate_square(number): total = 0 for n in range(number): total += n ** 2 print(f"計(jì)算結(jié)果:{total}") if __name__ == "__main__": # 必須加這句,否則Windows系統(tǒng)會(huì)報(bào)錯(cuò) # 創(chuàng)建4個(gè)進(jìn)程 processes = [] numbers = [10_000_000, 10_000_000, 10_000_000, 10_000_000] # 四個(gè)大數(shù) # 記錄開始時(shí)間 start_time = time.time() # 創(chuàng)建并啟動(dòng)進(jìn)程 for num in numbers: p = multiprocessing.Process(target=calculate_square, args=(num,)) processes.append(p) p.start() # 啟動(dòng)進(jìn)程(會(huì)立即返回,不會(huì)等待完成) # 等待所有進(jìn)程完成 for p in processes: p.join() # 阻塞主進(jìn)程,直到子進(jìn)程結(jié)束 # 計(jì)算總耗時(shí) print(f"總耗時(shí):{time.time() - start_time:.2f}秒")
3. 實(shí)現(xiàn)邏輯
主進(jìn)程(老板)
│
├─ 子進(jìn)程1(員工1)→ 獨(dú)立計(jì)算
├─ 子進(jìn)程2(員工2)→ 獨(dú)立計(jì)算
├─ 子進(jìn)程3(員工3)→ 獨(dú)立計(jì)算
└─ 子進(jìn)程4(員工4)→ 獨(dú)立計(jì)算
4. 注意事項(xiàng)
- 進(jìn)程間不能直接共享變量,需使用
Queue
或Pipe
通信 - 每個(gè)進(jìn)程消耗更多內(nèi)存(獨(dú)立內(nèi)存空間)
- 適合處理相互獨(dú)立的任務(wù)(如同時(shí)處理多個(gè)文件)
二、threading(多線程)
1. 模塊簡介
- 作用:創(chuàng)建多個(gè)線程(共享同一進(jìn)程內(nèi)存)
- 適用場景:文件讀寫、網(wǎng)絡(luò)請求等I/O等待型任務(wù)
- 核心特點(diǎn):受GIL限制,同一時(shí)刻只能有一個(gè)線程執(zhí)行Python字節(jié)碼
2. 案例詳解:同時(shí)下載文件與顯示進(jìn)度條
import threading import time import requests # 全局變量(線程共享) download_complete = False def download_file(url): global download_complete print("開始下載文件...") response = requests.get(url) with open("bigfile.iso", "wb") as f: f.write(response.content) download_complete = True print("\n下載完成!") def show_progress(): while not download_complete: print(".", end="", flush=True) # 不換行輸出點(diǎn) time.sleep(0.5) if __name__ == "__main__": # 創(chuàng)建兩個(gè)線程 download_thread = threading.Thread( target=download_file, args=("https://example.com/large-file.iso",) ) progress_thread = threading.Thread(target=show_progress) # 啟動(dòng)線程 download_thread.start() progress_thread.start() # 等待下載線程完成 download_thread.join() progress_thread.join() # 需要手動(dòng)停止進(jìn)度條線程
3. 實(shí)現(xiàn)邏輯
主線程
│
├─ 下載線程 → 執(zhí)行下載(遇到網(wǎng)絡(luò)等待時(shí),GIL釋放)
└─ 進(jìn)度條線程 → 打印進(jìn)度點(diǎn)
4. 注意事項(xiàng)
- 共享變量需使用
Lock
避免數(shù)據(jù)競爭 - 線程適合需要頻繁共享數(shù)據(jù)的場景(如GUI程序)
- 不要用多線程做數(shù)學(xué)計(jì)算(反而會(huì)更慢)
三、asyncio(協(xié)程)
1. 模塊簡介
- 作用:單線程內(nèi)通過任務(wù)切換實(shí)現(xiàn)高并發(fā)
- 適用場景:Web服務(wù)器、高頻I/O操作(如爬蟲)
- 核心機(jī)制:事件循環(huán)(Event Loop)驅(qū)動(dòng)協(xié)程切換
2. 案例詳解:異步批量請求網(wǎng)頁
import asyncio import aiohttp # 需要安裝:pip install aiohttp async def fetch_page(url): async with aiohttp.ClientSession() as session: # 創(chuàng)建會(huì)話 async with session.get(url) as response: # 發(fā)起請求 return await response.text() # 異步等待響應(yīng) async def main(): urls = [ "https://www.baidu.com", "https://www.taobao.com", "https://www.jd.com" ] # 創(chuàng)建任務(wù)列表 tasks = [fetch_page(url) for url in urls] # 并行執(zhí)行所有任務(wù) pages = await asyncio.gather(*tasks) # 關(guān)鍵點(diǎn):聚集任務(wù) # 輸出結(jié)果 for url, content in zip(urls, pages): print(f"{url} → 長度:{len(content)}") # 啟動(dòng)事件循環(huán) asyncio.run(main()) # Python 3.7+
3. 實(shí)現(xiàn)邏輯
事件循環(huán)(總調(diào)度員)
│
├─ 任務(wù)1:請求百度 → 遇到等待 → 掛起
├─ 任務(wù)2:請求淘寶 → 遇到等待 → 掛起
└─ 任務(wù)3:請求京東 → 遇到等待 → 掛起
當(dāng)某個(gè)請求返回時(shí),恢復(fù)對應(yīng)任務(wù)執(zhí)行
4. 注意事項(xiàng)
- 協(xié)程函數(shù)必須用
async def
定義 - 阻塞操作必須用
await
(否則會(huì)阻塞整個(gè)事件循環(huán)) - 需要配合異步庫使用(如
aiohttp
代替requests
)
三者的核心區(qū)別總結(jié)
特性 | multiprocessing | threading | asyncio |
---|---|---|---|
并行能力 | 真正多核并行 | 偽并行(受GIL限制) | 單線程并發(fā) |
內(nèi)存占用 | 高(獨(dú)立內(nèi)存空間) | 低(共享內(nèi)存) | 最低 |
適用場景 | CPU密集型任務(wù) | I/O密集型任務(wù) | 超高并發(fā)I/O任務(wù) |
代碼復(fù)雜度 | 中等(需處理進(jìn)程通信) | 低(但需處理鎖) | 高(需理解異步語法) |
如何選擇?
- 需要數(shù)學(xué)計(jì)算加速 → 選
multiprocessing
- 簡單I/O操作(如文件讀寫) → 選
threading
- 高性能網(wǎng)絡(luò)請求(如爬蟲) → 選
asyncio
- 混合型任務(wù) → 組合使用(如多進(jìn)程+協(xié)程)
通過這三個(gè)案例,可以明顯看出:多進(jìn)程像多個(gè)獨(dú)立工廠,多線程像工廠內(nèi)多個(gè)協(xié)作工人,協(xié)程則像一個(gè)人用超高效的時(shí)間管理法。理解這個(gè)核心差異后,就能根據(jù)實(shí)際需求選擇合適的工具了。
到此這篇關(guān)于Python多進(jìn)程、多線程、協(xié)程典型示例解析的文章就介紹到這了,更多相關(guān)Python多進(jìn)程、多線程、協(xié)程典型示例解析內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- python并發(fā)編程之多進(jìn)程、多線程、異步和協(xié)程詳解
- 深入淺析python中的多進(jìn)程、多線程、協(xié)程
- Python中安全地使用多進(jìn)程和多線程進(jìn)行數(shù)據(jù)共享
- python多進(jìn)程和多線程介紹
- python?logging多進(jìn)程多線程輸出到同一個(gè)日志文件的實(shí)戰(zhàn)案例
- 分析詳解python多線程與多進(jìn)程區(qū)別
- Python多線程與多進(jìn)程相關(guān)知識總結(jié)
- Python多進(jìn)程與多線程的使用場景詳解
- Python 多進(jìn)程、多線程效率對比
相關(guān)文章
Python數(shù)據(jù)結(jié)構(gòu)之Array用法實(shí)例
這篇文章主要介紹了Python數(shù)據(jù)結(jié)構(gòu)之Array用法實(shí)例,較為詳細(xì)的講述了Array的常見用法,具有很好的參考借鑒價(jià)值,需要的朋友可以參考下2014-10-10python教程之用py2exe將PY文件轉(zhuǎn)成EXE文件
py2exe是一個(gè)將python腳本轉(zhuǎn)換成windows上的可獨(dú)立執(zhí)行的可執(zhí)行程序(*.exe)的工具,這樣,你就可以不用裝python而在windows系統(tǒng)上運(yùn)行這個(gè)可執(zhí)行程序。2014-06-06Python HTMLTestRunner可視化報(bào)告實(shí)現(xiàn)過程解析
這篇文章主要介紹了Python HTMLTestRunner可視化報(bào)告實(shí)現(xiàn)過程解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-04-04Python 跨文件夾導(dǎo)入自定義包的實(shí)現(xiàn)
有時(shí)我們自己編寫一些模塊時(shí),跨文件夾調(diào)用會(huì)出現(xiàn)ModuleNotFoundError: No module named 'XXX',本文就來介紹一下解決方法,感興趣的可以了解一下2023-11-11解決cupy-cuda安裝下載報(bào)錯(cuò)以及速度太慢的問題
在嘗試下載Cupy-CUDA時(shí)可能會(huì)遇到報(bào)錯(cuò)"ERROR: THESE PACKAGES DO NOT MATCH THE HASHES FROM THE REQUIREMENTS FILE.",這通常是由于網(wǎng)絡(luò)問題導(dǎo)致的,出現(xiàn)這種情況時(shí),可以嘗試使用清華大學(xué)的鏡像源來加速下載,這樣不僅可以提高下載速度2024-09-09