我有以下问题:我和许多工人一起经营芹菜。在芹菜启动期间,我创建了几个子进程:
proc = subprocess.Popen("program", stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=cwd)
我需要这些子进程来启动,然后由芹菜工人(重复)使用。所以我将子进程保存到multiprocessing.Manager().dict() -类似于pool…
pool = multiprocessing.Manager().dict()
pool[proc_id] = proc
所有的子进程都可以从芹菜工人访问,但他们不工作-我发现管道在一瞬间被打破,当子进程通过池共享。那么第一个问题:是否有机会在其他进程(芹菜工人)之间共享子进程管道?
我还尝试保存分隔常规字典的管道。然后,当worker从池中获取子进程时,这些管道连接到子进程:
proc.stdin = dict_of_pipes[proc_id]
这个解决方案有时有效,但有时在字典中找不到管道-我猜是因为进程之间共享常规字典是不行的?
作为"程序",你可以想象/bin/bash. .解决了锁问题,字典永远不会同时被超过1个进程访问…
第二个问题-是否有可能打开新的管道来子进程?(从任何芹菜工人那里?)或者其他解决方案?
经过一些实验,我发现不可能打开管道到已经存在的子进程(我的第二个问题),并且我不能在进程之间复制(共享)现有的管道(我的主要问题)。
所以我这样解决它:每个子进程都用python的multiprocessing封装。进程,它实现了XML RPC服务器——这些"包装器"在芹菜启动时启动,或者在任何时候由芹菜工人启动。在包装器进程启动之后,它通过多处理发送它正在运行的端口。管道,这些端口保存在共享池中(multiprocessing.Manager().dict())。然后,芹菜工作程序就可以通过XML RPC包装器调用正在运行的子进程,而不用担心管道问题。XML RPC不是必需的,但它使代码更简单,更容易使用。
可以通过现有管道发送新管道。这里有一个问题:Python 2.6通过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])
这样,你就可以使用一个主管道来连接新实例化的子进程。