作業を行うために使用されるプロセス間で何が同期されているかを考えると、表示されている動作はそれほど驚くべきものではありPool
ません。関数の引数と戻り値のみが現在のコードで同期されるため、呼び出しプロセスで元の値を保持I
することは理にかなっています。x
y
現在のコードは最小限のテストケースだと思います。これは、を使用して1つの配列を別の配列にコピーするという意味のある実装が実際にはないため、面倒ですPool.map
。これは簡単な解決策ですが、実際のタスクが何であれ、それが一般化されるかどうかはわかりません。
import numpy as np
from multiprocessing import Pool
def I(v):
return v
if __name__ == "__main__": # this boilerplate is required on on Windows
x = np.random.random(100)
y = np.random.random(100)
pool = Pool()
y[:] = pool.map(I, x)
print(x == y) # [True, True, True, ...]
これにより、の各値がx
別のプロセスに渡され(何も行われない場合)、結果の値が返され、に割り当てられy
ます(pool.mapはリストを返します)。それはかなりばかげています。
もう少し洗練されたアプローチでは、コンストラクターで引数と引数x
を使用して、ワーカープロセスにコピーすることができます。これを行う例を次に示します。initializer
initargs
Pool
import numpy as np
from multiprocessing import Pool
def I(index):
return x[index]
def setup(value):
global x
x = value
if __name__ == "__main__":
x = np.random.random(100)
y = np.random.random(100)
pool = Pool(initializer=setup, initargs=(x,))
y[:] = pool.map(I, range(100))
print(x == y) # [True, True, True, ...]
ただし、これx
は一方向にのみコピーされることに注意してください。その値I
を変更した場合、変更はプロセス間で同期されません。
タスクが実際にソース配列とターゲット配列の両方への同期アクセスを必要とするものである場合は、試してみてくださいmultiprocessing.Array
。私はそれを直接経験したことはありませんが、y
それ自体の同期バージョンに置き換えることは可能であるはずです。残念ながら、同期によってプログラムの速度が低下する可能性があるため、本当に必要な場合を除いて、同期を行わないでください。