multiprocessing
とProcess
の場合、args
paramを設定することでValue, Array
を使用できます。
multiprocessing
とPool
を使用して、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)
print(arr[:])
以下のコードスニペット内でValue, Array
を使用しようとしています。
import multiprocessing
def do_calc(data):
# access num or
# work to update arr
newdata =data * 2
return newdata
def start_process():
print 'Starting', multiprocessing.current_process().name
if __name__ == '__main__':
num = Value('d', 0.0)
arr = Array('i', range(10))
inputs = list(range(10))
print 'Input :', inputs
pool_size = multiprocessing.cpu_count() * 2
pool = multiprocessing.Pool(processes=pool_size,initializer=start_process, )
pool_outputs = pool.map(do_calc, inputs)
pool.close() # no more tasks
pool.join() # wrap up current tasks
print 'Pool :', pool_outputs
私はこれの「理由」を知りませんでしたが、multiprocessing
(mp
)は、ほとんどのPool
メソッドに渡される関数に異なるピッカー/アンピッカーメカニズムを使用します。 _mp.Value
_、_mp.Array
_、_mp.Lock
_、...などで作成されたオブジェクトは、そのようなメソッドに引数として渡すことはできませんが、できます _mp.Process
_に引数として渡されますおよびmp.Pool()
のオプションのinitializer
関数に渡されます。後者のため、これは機能します。
_import multiprocessing as mp
def init(aa, vv):
global a, v
a = aa
v = vv
def worker(i):
a[i] = v.value * i
if __name__ == "__main__":
N = 10
a = mp.Array('i', [0]*N)
v = mp.Value('i', 3)
p = mp.Pool(initializer=init, initargs=(a, v))
p.map(worker, range(N))
print(a[:])
_
そしてそれは印刷します
_[0, 3, 6, 9, 12, 15, 18, 21, 24, 27]
_
これがプラットフォーム間でこれを機能させるために私が知っている唯一の方法です。
Linux-yプラットフォーム(mp
がfork()
を介して新しいプロセスを作成する場合)では、代わりに_mp.Array
_および_mp.Value
_(etc)オブジェクトをモジュールグローバルとして作成できます。時間前mp.Pool()
を実行します。 fork()
によって作成されたプロセスは、mp.Pool()
の実行時にモジュールのグローバルアドレス空間にあるものをすべて継承します。
しかし、それはfork()
をサポートしないプラットフォーム(「Windows」と読みます)ではまったく機能しません。