我有以下问题: 我和许多工人一起经营芹菜。在celery启动期间,我创建了几个子进程:
proc = subprocess.Popen("program", stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=cwd)
我需要这些子过程来启动并稍后由芹菜工人使用(反复)。所以我将子进程保存到multiprocessing.Manager()。dict() - 类似于池......
pool = multiprocessing.Manager().dict()
pool[proc_id] = proc
所有子流程都可以从芹菜工人那里访问,但是它们不起作用 - 我发现当通过池共享子流程时,管道会被破坏。 所以第一个问题:是否有机会在另一个流程(芹菜工人)之间共享子流程管道?
我还尝试将管道保存到分开的常规字典中。然后,当worker从池中获取子进程时,这些管道将连接到子进程:
proc.stdin = dict_of_pipes[proc_id]
这个解决方案有时会起作用,但有时候在字典中找不到管道 - 我之间因为在进程之间共享常规字典不行吗?
作为“程序”你可以想象/ bin / bash。锁定已解决,字典永远不会被超过1个进程一次访问...
第二个问题 - 是否可以打开新管道进行子流程? (来自任何芹菜工人?)或其他解决方案?
答案 0 :(得分:3)
经过一些实验后,我发现无法打开现有子流程的管道(我的第二个问题),并且我无法在流程之间复制(共享)现有管道(我的主要问题)。
所以我这样解决了:每个子进程都包含python的multiprocessing.Process,它实现了XML RPC服务器 - 这些"包装器"芹菜开始时或芹菜工人随时开始。 启动包装器进程后,它会通过multiprocessing.Pipe发送正在运行的端口,这些端口保存在共享池中(multiprocessing.Manager()。dict())。然后,芹菜工作者可以通过XML RPC包装器调用运行的子进程,而不会出现管道问题。 XML RPC不是必需的,但它使代码更简单,更易于使用。
答案 1 :(得分:0)
您可以通过现有管道发送新管道。 有一个问题: Python 2.6 send connection object over Queue / Pipe / etc
这个答案对我有用。
# Somewhere in the main process code
#
#
in, out = Pipe()
reduced = reduction.reduce_connection(out)
in_old_pipe.send(reduced)
.
# Somewhere else in the subprocess code
.
.
reduced = out_old_pipe.recv()
newi = reduced[0](*reduced[1])
这样,您可以使用主管道连接新实例化的子进程。