【问题标题】:Communicating with a running process与正在运行的进程通信
【发布时间】:2012-04-17 09:14:19
【问题描述】:

我们有:

  • 基于 Python 的服务器 (A)
  • 一个正在运行的命令行应用程序(在同一台 Linux 机器上)能够读取 stdin,计算某些内容并将输出提供给 stdout (B)

如何将输入从 (A) 发送到 (B) 的 stdin,并等待 (B) 的答复,即阅读其 stdout,最好(最优雅)的方式是什么?

【问题讨论】:

  • 无论您在此处做什么,请小心避免 A 和 B 都在等待对方继续进行的死锁。

标签: python ipc


【解决方案1】:

如果您使用标准库中的 Python 的 subprocess 模块生成 (B),则可以将 (B) 的 stdinstdout 设置为 (A) 可读和可写的字节缓冲区。

b = Popen(["b.exe"], stdin=PIPE, stdout=PIPE)
b.stdin.write("OHAI\n")
print(b.stdout.readline())

对于您给定的示例,使用communicate 是最简单的,因为这样可以避免您的死锁:

b = Popen(["b.exe"], stdin=PIPE, stdout=PIPE)
b_out = b.communicate("OHAI\n")[0]
print(b_out)

http://docs.python.org/release/3.1.3/library/subprocess.html

http://docs.python.org/release/3.1.3/library/subprocess.html#subprocess.Popen.communicate

如果有很多双向通信,则应注意避免由于缓冲区已满而导致的死锁。如果您的通信模式出现此类问题,您应该考虑改用socket 通信。

【讨论】:

  • 不幸的是,Popen.communicate() 不是选项,因为子进程 (B) “永远”运行。
  • 然后像第一个例子一样通过 stdin.write 和 stdout.read 进行通信。
【解决方案2】:

正如@Deestan 指出的 subprocess,module 是一个优雅且经过验证的过程。当我们必须从 python 运行命令时,我们经常使用子进程。

我们的主要涉及运行命令,主要是内部构建,并捕获其输出。我们运行这些命令的包装器看起来是这样的。

import subprocess
def _run_command( _args, input=[],withShell=False):
    """
    Pass args as array, like ['echo', 'hello']
    Waits for completion and returns
    tuple (returncode, stdout, stderr)
    """
    p = subprocess.Popen(_args, shell = withShell,
                         stdin=subprocess.PIPE, stdout=subprocess.PIPE)
    [p.stdin.write(v) for v in input]
    stdout, stderr = p.communicate()
    return p.returncode, stdout, stderr

_,op,er = _run_command(['cat'],["this","is","for","testing"])
value="".join(op)
print value

_,op,er = _run_command(['ls',"/tmp"])
value="".join(op)
print value

如果您对 B 的输入很少,则子流程为

【讨论】:

  • 拜托,正如我上面提到的,如果子进程运行很长时间(不是一次)怎么办?
  • 在您的问题中详细说明进程 B 如何启动和终止。给出样本输入/输出。 PS:如果进程A和B是异步启动的,那么你应该选择socket。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多