[英]Python: How to use Value and Array in Multiprocessing pool
對於使用Process
multiprocessing
Process
,我可以通過設置args
param來使用Value, Array
。
使用Pool
multiprocessing
時,如何使用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
方法的函數使用不同的pickler / unpickler機制。 這是因為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.Pool()
之前隨時創建mp.Array
和mp.Value
(etc)對象作為模塊全局變量。 fork()
創建的進程在mp.Pool()
執行時繼承模塊全局地址空間中的mp.Pool()
。
但是,這在不支持fork()
平台上(閱讀“Windows”)根本不起作用。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.