Python 提供了多種併發工具,讓程式可以在等待 I/O 時處理其他任務,或通過多行程利用多個 CPU 核心。本文介紹 threadingmultiprocessingasyncioconcurrent.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庫提供了非同步程式設計的能力,允許你編寫單執行緒的併發程式碼。通過使用asyncawait關鍵字,你可以在不阻塞主執行緒的情況下執行多個操作。

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中的併發程式設計。