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
これは、配列に対して読み取りまたは書き込みを行っているときに、Lock
自動的に作成されたがループ全体のアクセスを同期しないことが原因でした! Array
マスター プロセスはArray
、ワーカーがロックを取得する間に変更を行ったり来たりします。
これを避けるためRLock
に、. をすべてのワーカーに渡して、誰もがアトミック操作を実行できるようにしました (あなたの状況では、勾配計算のエラーを防ぐために読み取りと書き込みがアトミックであることが重要であると確信しています)。RLock
Array
Lock
Array
RLock
編集:
別の代替案のように見えますmmap
が、その使用法と、変更がここで必要に応じて機能するかどうかについてコメントすることはできません.