我正在尝试从multiprocessing.Process继承一个子类,它将为每个瞬间提供一个队列,以便队列可用于捕获目标的返回值。 但问题是multiprocessing.Process.start()使用subprocess.Popen(https://github.com/python/cpython/blob/master/Lib/multiprocessing/process.py)创建进程并在其中运行目标。有没有办法在不定义/重载整个Process模块的情况下重载它。
这就是我要做的事情:
class Mprocessor(multiprocessing.Process):
def __init__(self, **kwargs):
multiprocessing.Process.__init__(self, **kwargs)
self._ret = Queue.Queue()
def run(self):
self._ret.put(multiprocessing.Process.run(self))
def getReturn(self):
if self._ret.empty:
return None
return self._ret.get()
这里我尝试在类中创建一个multiprocessig.Queue。 我重写'run'方法,所以当它被执行时,目标的返回值被放入队列中。 我有一个'getReturn'方法,它使用Mprocess类在main函数中调用。只有在'Mprocess.isalive()'方法(为multiprocessing.Process定义)返回false时才应调用此方法。 但是这种机制不起作用,因为当我调用'Mprocess.start()'时,它会创建一个子进程,在自己的环境中运行目标。 我想知道是否有一种方法可以在start方法中使用队列来获取返回值,并避免目标有一个队列参数进行通信。 我想概括一下这个模块。 我不希望我的方法被定义为有一个队列来获取返回值。 我想要一个模块,以便它可以适用于任何函数,因为我计划有一个管理器方法,它接受一个dict [“process_name / ID”:methods / targets],一个dict [“进程名称/ ID “:[argument_list]]并为每个目标创建一个进程并返回一个dict [”process_name / ID“:(返回元组))。 任何想法都会受到欢迎。
修改 经理职能:
def Processor_call(func = None, func_args = None):
if sorted(func.keys()) != sorted(func_args()):
print "Names in func dict and args dict doesn't match"
return None
process_list = multiprocessing.Queue()
for i in func.keys():
p = Mprocessor(name = i, target = func[i], args = tuple(func_args[i]))
process_list.put(p)
p.start()
return_dict = {}
while not process_list.empty():
process_wait = process_list.get()
if not process_wait.is_alive():
process_wait.join()
if process_wait.exitcode == 0:
return_dict[process_wait.name] = process_wait.getReturn()
else:
print "Error in process %s, status not availabe" %process_wait.name
else:
join_process.put(process_wait)
return return_dict
编辑:目标函数应该如下所示。
def sum(a , b):
return a + b
我不想将队列传递给函数,并返回队列。 我想创建一个通用模块,以便任何现有方法都可以使用多处理而不需要对其定义进行任何更改,因此可以维护与其他模块的接口。 我不希望将一个函数设计为仅作为一个进程运行,我想拥有通用接口,以便其他模块也可以将此函数用作普通方法,而不必费心从队列中读取以获得返回值。
答案 0 :(得分:1)
评论:...以便我从start方法开始的流程中获取返回值
这对我有用,例如:
类Mprocessor
class Mprocessor(multiprocessing.Process):
def __init__(self, queue, **kwargs):
multiprocessing.Process.__init__(self, **kwargs)
self._ret = queue
def run(self):
return_value = self._target( *self._args )
self._ret.put((self.name, return_value))
time.sleep(0.25)
exit(0)
启动流程并等待返回值
def Processor_call(func=None, func_args=None):
print('func=%s, func_args=%s' % (func, func_args))
ret_q = multiprocessing.Manager().Queue()
process_list = []
for i in func.keys():
p = Mprocessor(name=i, target=func[i], args=(func_args[i],), queue=ret_q)
p.start()
process_list.append(p)
time.sleep(0.1)
print('Block __main__ until all process terminated')
for p in process_list:
p.join()
print('Aggregate alle return values')
return_dict = {}
while not ret_q.empty():
p_name, value = ret_q.get()
return_dict[p_name] = value
return return_dict
__ main __
if __name__ == '__main__':
rd = Processor_call({'f1':f1, 'f2':f1}, {'f1':1, 'f2':2})
print('rd=%s' % rd)
<强>输出强>:
func = {'f1':,'f2':},func_args = {'f1':1,'f2':2}
pid:4501开始2
pid:4501正在运行
pid:4500开始1
pid:4500运行
阻止__main__直到所有进程终止为止 pid:4501正在运行
pid:4500运行
pid:4501正在运行
pid:4500运行
pid:4501终止
pid:4500终止
聚合等位基因返回值
rd = {'f1':1,'f2':2}
使用Python测试:3.4.2和2.7.9
问题:是否可以继承multiprocessing.Process与主进程通信
是的,这是可能的。但不使用class object
,因为process
使用了class object
自己的副本。
您必须使用global Queue object
并将其传递给process
。