【问题标题】:Subprocess starting two processes instead of one子进程启动两个进程而不是一个
【发布时间】:2012-04-24 20:11:29
【问题描述】:

我正在使用子进程来启动一个进程并让它在后台运行,它是一个服务器应用程序。该进程本身是一个带有瘦包装器的 java 程序(这意味着我可以将它作为可执行文件启动,而无需显式调用 java)。

我正在使用 Popen 来运行该进程,当我设置 shell=False 时,它​​会运行,但它会生成两个进程而不是一个。第一个进程将 init 作为其父进程,当我通过 ps 检查它时,它只显示原始命令。但是,第二个进程会显示扩展的 java 参数(-D 和 -X 标志)——这是我期望看到的,也是我手动运行命令时进程的样子。

有趣的是,当我设置 shell=True 时,命令失败。该命令确实有一条帮助消息,但它似乎并不表明我的参数列表有问题(不应该有)。除了 Popen 的 shell 命名参数之外,一切都是一样的。 我在 Ubuntu 上使用 Python 2.7。不太确定这里发生了什么,任何帮助表示赞赏。我想 java 命令可能正在执行 exec/fork 并且由于某种原因,当我通过 Python 启动父进程时它并没有死。

我看到了这个SO question,它看起来很有希望,但并没有改变我正在经历的行为。

【问题讨论】:

  • 这个问题很模糊——没有包装器和调用的来源,任何答案都是猜测。话虽如此,鉴于所描述的症状,有一些相当充分的理由可以使这种猜测受到教育。

标签: python subprocess


【解决方案1】:

这实际上是一个关于包装器的问题,而不是关于 Python 的问题——从任何其他语言运行它都会得到相同的行为。

为了获得您想要的行为,包装器希望它调用 JVM 的行如下所示:

exec java -D... -cp ... main.class.here "$@"

...而不是前面缺少exec

java -D... -cp ... main.class.here "$@"

在前一种情况下,包装器的进程映像被它调用的JVM 的进程映像替换;在后者中,包装器等待JVM退出,然后继续运行。

如果包装器在 JVM 退出后进行任何清理,使用 exec 将防止这种情况发生,因此将是错误的事情 - 在这种情况下,您会希望包装器仍然存在在 JVM 运行时运行,否则之后将无法执行清理。

请注意,如果包装器负责分离子进程,则它需要能够关闭打开的文件句柄才能正确执行此操作。如果您的父进程的文件描述符多于仅打开的标准输入、标准输出和标准错误,请考虑将 close_fds=True 传递给您的 Popen 调用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-01-16
    • 1970-01-01
    • 2013-01-25
    • 2015-03-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-06-14
    相关资源
    最近更新 更多