【问题标题】:is it possible to share subprocess pipe between processes (celery workers)?是否可以在进程(芹菜工人)之间共享子进程管道?
【发布时间】:2014-05-28 22:59:27
【问题描述】:

我有以下问题: 我和许多工人一起经营芹菜。在 celery 启动期间,我创建了几个子进程:

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

芹菜工人可以访问所有子进程,但它们不起作用 - 当子进程通过池共享时,我发现管道瞬间损坏。 所以第一个问题:有没有机会在另一个进程(芹菜工人)之间共享子进程管道?

我还尝试将管道保存到单独的常规字典中。然后当工作者从池中获取子进程时,这些管道被连接到子进程:

proc.stdin = dict_of_pipes[proc_id]

此解决方案有时有效,但有时在字典中找不到管道 - 我怀疑是因为在进程之间共享常规字典不行吗?

作为“程序”你可以想象 /bin/bash.锁定已解决,字典一次不会被超过 1 个进程访问...

第二个问题 - 是否可以为子进程打开新管道? (来自任何芹菜工人?)或其他解决方案?

【问题讨论】:

    标签: python subprocess ipc celery


    【解决方案1】:

    经过一些实验,我发现无法打开现有子进程的管道(我的第二个问题),并且我无法在进程之间复制(共享)现有管道(我的主要问题)。

    所以我这样解决它:每个子进程都用 python 的 multiprocessing.Process 包装,它实现 XML RPC 服务器 - 这些“包装器”在 celery 启动时启动,或者由 celery 工人随时启动。 包装进程启动后,它通过 multiprocessing.Pipe 发送他正在运行的端口,这些端口保存在共享池中(multiprocessing.Manager().dict())。然后,Celery 工作人员可以通过 XML RPC 包装器调用正在运行的子进程,而不会遇到管道问题。 XML RPC 不是必需的,但它使代码更简单易用。

    【讨论】:

      【解决方案2】:

      有可能,您可以通过现有管道发送新管道。 对此有一个问题: 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])
      

      这样,您可以使用主管道连接新实例化的子进程。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2022-10-25
        • 2010-12-13
        • 2015-06-01
        • 2013-12-24
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多