我一直在玩multiprocessing
自閱讀本文以後發現更新mp.Array
中的數據並不難 - 我得到的一點是,使用循環迭代Array
時訪問不是原子的。下面的代碼片段設置使用mp.Process
一個簡單的主工人組(使用Pool
將是更好的,但是這是更快的對我來說),其中一個mp.Array
用於其主會經常變化的數據進行同步(儘可能快,因爲它可以)
from multiprocessing import Process, RLock, Array
from time import sleep
def worker(n, array, arrayLock):
while True:
arrayLock.acquire()
print("Worker: %i -> %s" % (n, ",".join(str(i) for i in array)))
arrayLock.release()
sleep(n + 1)
if __name__ == '__main__':
arrayLock = RLock()
array = Array('i', range(10), lock=arrayLock)
pd = {}
for i in range(3):
pd[i] = Process(target=worker, args=(i, array, arrayLock))
pd[i].start()
try:
while True:
arrayLock.acquire()
for i in range(len(array)):
array[i] = -array[i]
arrayLock.release()
except KeyboardInterrupt:
pass
for p in pd.values():
p.terminate()
在下面的輸出
~> python mp_shared.py
Worker: 0 -> 0,1,2,3,4,5,6,7,8,9
Worker: 1 -> 0,-1,-2,-3,-4,-5,-6,-7,-8,-9
Worker: 2 -> 0,1,2,3,4,5,6,7,8,9
Worker: 0 -> 0,-1,-2,-3,-4,-5,-6,-7,-8,-9
Worker: 1 -> 0,-1,-2,-3,-4,-5,-6,-7,-8,-9
Worker: 0 -> 0,1,2,3,4,5,6,7,8,9
跨進程更新數據所得只是在Array
改變值的問題。我打了一個問題,結果是這樣的,雖然(注意數據的交替跡象)
Worker: 0 -> 0,-1,2,-3,4,-5,6,-7,8,-9
Worker: 1 -> 0,-1,2,-3,4,-5,6,-7,8,-9
Worker: 2 -> 0,-1,2,-3,4,-5,6,-7,8,-9
這是由事實爲Array
自動創建Lock
不會同步整個環路接入引起的當我正在閱讀或寫入陣列時!主進程將壓縮Array
中的工作人員鎖定採集之間的變化。
爲了避免這種情況,我只是創建了自己的RLock
(需要有一個RLock
作爲觸摸Array
使得收購,這將阻止如果你已經獲得了Lock
),用於與Array
使用。我將RLock
傳遞給所有工作人員,以便他們每個人都可以進行原子操作(在您的情況下,我確信讀取和寫入操作非常重要,以防止梯度計算出現錯誤)。
編輯:
另一種選擇似乎是mmap
,但我不能在它的使用評論,並在改變工作如下期望。
您可以將每個批次與網絡權重的狀態配對嗎?即將權重與批次一起排隊。 –