Python 提供了多種併發工具,讓程式可以在等待 I/O 時處理其他任務,或通過多行程利用多個 CPU 核心。本文介紹 threading、multiprocessing、asyncio 和 concurrent.futures 的基本用法與適用場景。
1. 執行緒(Threading)
Python 的 threading 模組允許在同一個行程內建立多個執行緒。執行緒共享記憶體,適合網路請求、檔案讀寫等 I/O 密集型任務,但共享狀態也會帶來競態條件和死鎖風險。在常見的 CPython 實現中,GIL 會限制多個執行緒同時執行 Python CPU 密集型程式碼,因此執行緒並不等同於 CPU 並行。
1.1 執行緒的基本使用
import threading
def print_numbers():
for i in range(5):
print(i)
# 创建线程
thread = threading.Thread(target=print_numbers)
thread.start()
thread.join()
2. 多行程(Multiprocessing)
為了繞過Python的全域直譯器鎖(GIL),multiprocessing模組允許你建立多個行程。每個行程有自己的記憶體空間和Python直譯器,因此可以實現真正的平行計算。
2.1 多行程的基本使用
from multiprocessing import Process
def print_numbers():
for i in range(5):
print(i)
# 创建进程
process = Process(target=print_numbers)
process.start()
process.join()
3. 非同步程式設計(asyncio)
Python的asyncio庫提供了非同步程式設計的能力,允許你編寫單執行緒的併發程式碼。通過使用async和await關鍵字,你可以在不阻塞主執行緒的情況下執行多個操作。
3.1 非同步程式設計的基本使用
import asyncio
async def print_numbers():
for i in range(5):
print(i)
await asyncio.sleep(1)
# 运行事件循环
asyncio.run(print_numbers())
4. 併發執行的高階工具
Python還提供了一些高階工具來簡化併發程式設計,如concurrent.futures模組,它提供了執行緒池和行程池的高階介面。
4.1 使用執行緒池
from concurrent.futures import ThreadPoolExecutor
def perform_task(x):
return x * x
with ThreadPoolExecutor(max_workers=5) as executor:
results = list(executor.map(perform_task, range(5)))
4.2 使用行程池
from concurrent.futures import ProcessPoolExecutor
def perform_task(x):
return x * x
with ProcessPoolExecutor(max_workers=5) as executor:
results = list(executor.map(perform_task, range(5)))
5. 總結
Python 的併發工具解決的是不同問題:I/O 密集型任務通常適合執行緒或 asyncio,CPU 密集型任務通常適合多行程。選擇之前應先判斷瓶頸來自等待還是計算,再考慮共享狀態、錯誤處理和任務取消等工程成本。
這篇文章基於Python官方說明文件中的併發執行部分,介紹了Python中實現併發執行的主要模組和工具,以及它們的使用示例。希望這能幫助你更好地理解和應用Python中的併發程式設計。