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

Python 多執行緒程式設計實戰:Thread、Lock、GIL 與多核限制

     編輯:更多程式設計知識

Python threading 模組提供高階執行緒介面,但受限於全域解譯器鎖(GIL),CPU 密集型任務無法真正並行。本文涵蓋執行緒建立、共享資料競態條件、鎖機制、GIL 影響與替代方案。

基本執行緒建立


import threading, time

def loop():
    print('thread %s is running...' % threading.current_thread().name)
    for n in range(1, 6):
        print('thread %s >>> %d' % (threading.current_thread().name, n))
        time.sleep(1)
    print('thread %s ended.' % threading.current_thread().name)

t = threading.Thread(target=loop, name='LoopThread')
t.start()
t.join()
print('thread %s ended.' % threading.current_thread().name)
  • 主執行緒名為 MainThread。
  • join() 等待執行緒結束。

共享資料競態條件


balance = 0

def change_it(n):
    global balance
    balance += n
    balance -= n

def run_thread(n):
    for _ in range(100000):
        change_it(n)

t1 = threading.Thread(target=run_thread, args=(5,))
t2 = threading.Thread(target=run_thread, args=(8,))
t1.start(); t2.start()
t1.join(); t2.join()
print(balance)  # 可能非 0

因 balance += n 非原子操作(讀取、計算、寫入),多執行緒交替執行導致資料錯誤。

使用 Lock 保護關鍵區段


lock = threading.Lock()

def run_thread(n):
    for _ in range(100000):
        lock.acquire()
        try:
            change_it(n)
        finally:
            lock.release()
  • acquire() 取得鎖,release() 釋放鎖。
  • 務必用 try/finally 確保釋放,避免死結。
  • 鎖會將並行區段序列化,降低效能。

GIL:多核 CPU 的障礙

  • CPython 解譯器擁有 Global Interpreter Lock (GIL),同一時間僅允許一條執行緒執行位元碼。
  • 每 100 條位元碼釋放一次 GIL,讓其他執行緒有機會執行。
  • 結果:多執行緒在 Python 中只能交替執行,無法利用多核。即使 100 條執行緒跑在 100 核心,CPU 使用率仍約 1 核心。

驗證 GIL 影響


import threading, multiprocessing

def cpu_loop():
    x = 0
    while True:
        x ^= 1

for _ in range(multiprocessing.cpu_count()):
    threading.Thread(target=cpu_loop).start()

啟動 N 條死迴圈執行緒(N = 核心數),觀察 CPU 使用率僅約 100~170%,遠低於理論值。

解決方案

小結

Python 多執行緒適合 I/O 密集型任務(網路請求、檔案讀寫)。CPU 密集型請改用多進程或 asyncio 協程。理解 GIL 限制是設計高效能 Python 系統的關鍵。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
需求方案
CPU 密集型並行使用 multiprocessing 多進程(各自獨立 GIL)
I/O 密集型並行threading、asyncio、concurrent.futures 均可
需 C 擴充模組繞過 GIL撰寫 C/C++ 擴充(如 NumPy、Pandas 內部實作)