在python多处理中,是否有类似Process.return_value()的东西? 为什么不,有什么选择? (除了使用队列)
背景: 目前,我的代码包含许多像这样的函数,这些函数对大量数据进行操作,这些数据是numpy数组(a,b)
b= f(a)
def f(a):
# do some work here
return b
我可以像这样并行化每个函数:
plist=[]
for i in range(ncores):
p= Process(target=f, args=(a[i::ncores]))
p.start()
plist.append(p)
这会使代码的这一部分加速因子ncores。问题是获得返回值:
for i, p in enumerate(plist):
p.join()
b[i::ncores]= p.return_value()
我找不到通过p检索返回值的方法。我不明白为什么不可能这样,因为p可以与核心上的进程通信。
现在,我正在使用Queue来获取返回值,但我发现它们有点麻烦:我必须将Queue和一个标识符传递给每个函数并将结果和ID放入队列:
def f(a, Queue=Queue, ID=-1):
# do some work here
if ID==-1:
# normal interface
return b
else:
# parallel interface
Queue.put([ID, b])
然后当我读出队列时,我必须将ID与原始数组匹配:
for i in range(ncores):
ID, result= Queue.get()
b[ID::ncores]= result
plist[ID].join()
有没有更短的方法来实现这一目标?
我尝试将字典或列表作为关键字传递给结果,这适用于线程,但不适用于多处理。
答案 0 :(得分:0)
什么是回报值?
如果它是简单的类似数组或数字,您可以将共享内存容器传递给它可以存储其结果的Process
实例。如果我们想象你只想在多个进程中求和一个数组:
from multiprocessing import Process,Value
import ctypes as C
import numpy as np
def func(input,output):
# do something with input
# put the result in output
output.value = input.sum()
def launch_processes(n):
outputs = []
jobs = []
for ii in range(n):
input = np.arange(ii)
# here use a synchronised wrapper to store the result of the func run
# This can be replaced with an Array instance if an array is returned
output = Value(C.c_size_t)
job = Process(target=func,args=(input,output))
outputs.append(output)
jobs.append(job)
job.start()
for job in jobs:
job.join()
for output in outputs:
print output.value
launch_processes(10)
执行上述操作的更简洁方法是通过子类化Process将作业封装在单个对象中:
from multiprocessing import Process,Value
import ctypes as C
import numpy as np
class Job(Process):
def __init__(self,input):
super(Job,self).__init__()
self.retval = Value(C.c_size_t)
self.input = input
def run(self):
self.retval.value = self.input.sum()
def launch_processes(n):
jobs = []
for ii in range(n):
job = Job(np.arange(ii))
job.start()
jobs.append(job)
for job in jobs:
job.join()
print job.retval.value
launch_processes(10)