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

Python 多進程變數共享機制深度解析:Manager、Value/Array 與同步鎖

     編輯:更多程式設計知識

Python multiprocessing 模組中,進程間記憶體隔離導致全域變數無法直接共享。本文透過實驗驗證問題本質,系統介紹 Manager、Value/Array 兩大共享機制,並深入探討資料同步與鎖機制。

問題重現:全域列表為何為空?


from multiprocessing import Process
import os

vip_list = []

def testFunc(cc):
    vip_list.append(cc)
    print 'process id:', os.getpid()

if __name__ == '__main__':
    threads = []
    for ll in range(10):
        t = Process(target=testFunc, args=(ll,))
        t.daemon = True
        threads.append(t)
    for t in threads: t.start()
    for t in threads: t.join()
    print vip_list  # 輸出:[]

原因:每個進程擁有獨立記憶體空間,子進程修改的是複製品,父進程原列表不變。

方案一:Manager 代理物件(推薦複雜資料結構)


from multiprocessing import Process, Manager

manager = Manager()
vip_list = manager.list()  # 共享列表代理

# ... 其餘相同 ...
# 輸出:[3, 2, 1, 7, 5, 0, 6, 8, 4, 9](順序不定)

Manager 啟動一個伺服器進程持有 Python 物件,其他進程透過代理操作,支援 list, dict, Namespace, Lock, Queue 等類型。

方案二:共享記憶體 Value/Array(高效能、基本類型)


from multiprocessing import Process, Value, Array

def f(n, a):
    n.value = 3.1415927
    for i in range(len(a)):
        a[i] = -a[i]

if __name__ == '__main__':
    num = Value('d', 0.0)        # 雙精度浮點數
    arr = Array('i', range(10))  # 有號整數陣列
    p = Process(target=f, args=(num, arr))
    p.start(); p.join()
    print num.value  # 3.1415927
    print arr[:]     # [0, -1, -2, -3, -4, -5, -6, -7, -8, -9]

型別代碼:'d'(double), 'i'(int), 'f'(float), 'c'(char) 等。

進階議題:資料競爭與同步鎖

即使共享變數,並發修改仍會導致資料不一致:


from multiprocessing import Process, Manager

manager = Manager()
sum = manager.Value('i', 0)

def testFunc(cc):
    sum.value += cc  # 非原子操作:讀取-修改-寫入

# 100 個進程各加 1,預期 100,實際常 < 100

使用 Lock 保護臨界區


from multiprocessing import Process, Manager, Lock

lock = Lock()
manager = Manager()
sum = manager.Value('i', 0)

def testFunc(cc, lock):
    with lock:
        sum.value += cc

# ... 建立進程時傳入 lock ...
# 輸出穩定為 100

效能考量與最佳實踐建議

「通常在進程間共享資料並非最佳選擇,因同步議題複雜;採用 Actor 模型透過訊息傳遞溝通通常更佳。盡可能避免共享狀態。」 —— Python 官方文檔

替代架構模式

  • 生產者-消費者:multiprocessing.Queue(內建鎖、線程安全)
  • Map-Reduce:multiprocessing.Pool.map() 自動分發收集
  • 共享唯讀資料:fork 時複製(Copy-on-Write),無需額外機制
  • 外部儲存:Redis、資料庫、共享檔案系統

參考資源

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved