[英]How to make a multiprocessing.Array process safe in python
在構造multiprocessing.Array
時,構造函數需要一個參數lock
。 默認設置為True
據我了解,當lock
標志設置為True
時,由此創建的multiprocessing.Array
應該是過程安全的。 但是,我無法驗證行為。
我正在使用以下代碼片段來驗證行為:
import multiprocessing
def withdraw(balance):
for _ in range(10000):
balance[0] = balance[0] - 1
def deposit(balance):
for _ in range(10000):
balance[0] = balance[0] + 1
balance = multiprocessing.Array('f',[1000],lock=True) ### Notice lock=True passed explicitly
p1 = multiprocessing.Process(target=withdraw, args=(balance,))
p2 = multiprocessing.Process(target=deposit, args=(balance,))
p1.start()
p2.start()
p1.join()
p2.join()
print("Final balance = {}".format(balance[0]))
每次運行此代碼時,由於競爭條件影響運行,我都會看到不同的最終結果。
你能幫我理解我在做什么和/或理解錯誤嗎? 根據我的理解,我發布的代碼片段應該總是打印 1000
鎖並不像你想象的那么原子。 它只包裝每個單獨的讀取或寫入。 我認為,在讀取當前值和寫入新值之間的間隙中,另一個進程已經跳入並保存了一個新值。 保存此更改時,這些更改將被破壞。
有一個針對Multiprocessing.Value的注釋記錄在案,這是有見地的......
如果您將讀取和寫入都綁定到單個事務中,並使用描述的get_lock()
,它將滿足您的期望......
def deposit(balance):
for _ in range(10000):
with balance.get_lock():
balance[0] = balance[0] + 1
def withdraw(balance):
for _ in range(10000):
with balance.get_lock():
balance[0] = balance[0] - 1
為了有趣和理解,您可以將for
循環包裝在鎖中並觀察它按順序執行所有提款,然后釋放鎖並按順序執行所有存款,因此:
def withdraw(balance):
with balance.get_lock():
for _ in range(1, 1001):
balance[0] = balance[0] - 1
sys.stdout.write(f'w {balance[0]}\n')
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.