首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Python 多執行緒同步機制詳解:從原子操作到 Lock、RLock、Semaphore、Event、Condition

     編輯:Java 相關知識

為什麼需要同步?

多執行緒同時存取共享資源(如計數器 counter += 1)時,單一運算實際分三步:讀取、計算、寫回。若執行緒在讀取後被切換,另一執行緒也讀到舊值,最終導致寫回值錯誤,這就是「臟資料」問題。

同步工具階層

1. 原子操作

CPython 的 GIL 保證單一 bytecode 指令不可中斷。以下操作是執行緒安全的:

  • 讀/寫實例屬性、全域變數
  • 列表/字典的單一操作(append、pop、clear、索引存取)

注意:「讀取→修改→寫回」的複合操作(如 x = x + 1)不是原子的。

2. Lock(互斥鎖)

import threading
lock = threading.Lock()

lock.acquire()
try:
    # 存取共享資源
finally:
    lock.release()

# Python 2.5+ 建議用 with 區塊
with lock:
    # 存取共享資源

acquire(blocking=False) 可嘗試非阻塞取得鎖。

3. RLock(可重入鎖)

同一執行緒可重複 acquire() 不會自我阻塞,解決「外層已持有鎖,內層函式又要鎖」的巢狀呼叫死結。

rlock = threading.RLock()
def outer():
    with rlock:
        inner()   # 內層也用同一把 rlock,不會卡住
def inner():
    with rlock:
        pass

4. Semaphore(信號量)

內部計數器控制同時存取的執行緒數,適合「資源池」場景(如資料庫連線池、HTTP 連線池)。

# 最多 10 條連線
pool_sema = threading.BoundedSemaphore(10)

with pool_sema:
    # 使用連線
    pass

BoundedSemaphore 會在 release() 次數超過 acquire() 時拋異常,防止邏輯錯誤。

5. Event(事件旗標)

簡單的「等待/通知」機制,一個旗標,多執行緒可 wait() 等待,單一執行緒 set() 喚醒全體。

evt = threading.Event()
# 消費者
evt.wait()          # 阻塞直到 set()
# 生產者
evt.set()           # 喚醒所有等待者
evt.clear()         # 重置旗標

6. Condition(條件變數)

Event 的進階版,綁定一把鎖,支援「等待特定條件」並自動釋放/重新取得鎖,經典「生產者-消費者」模式首選。

cond = threading.Condition()

# 生產者
with cond:
    produce_item()
    cond.notify()   # 或 notifyAll()

# 消費者
with cond:
    while not item_available():
        cond.wait() # 釋放鎖並阻塞,被喚醒後重新取得鎖
    consume_item()

wait(timeout) 可設超時避免永久阻塞。

實戰範例:銀行帳戶轉帳

balance = 0
lock = threading.Lock()

def change(n):
    global balance
    with lock:
        balance += n
        balance -= n   # 應回到 0

threads = [threading.Thread(target=change, args=(i,)) for i in (5, 8, 9)]
for t in threads: t.start()
for t in threads: t.join()
print(balance)  # 穩定輸出 0

未加鎖時,高併發下結果會是隨機非零值。

總結選型指南

工具適用場景關鍵特性
原子操作單一簡單資料型別無鎖、最高效
Lock一般互斥同步不可重入、輕量
RLock巢狀/遞迴呼叫同步可重入、追蹤遞迴層級
Semaphore限流、資源池計數器、允許 N 並發
Event單次廣播通知旗標、無鎖關聯
Condition複雜等待/通知協議綁定鎖、支援條件判斷
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved