我正在使用子进程来启动一个进程并让它在后台运行,它是一个服务器应用程序。该进程本身是一个带有薄包装器的 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 的问题——从任何其他语言运行它都会得到相同的行为。
为了获得您想要的行为,包装器希望调用 JVM 的行如下所示:
exec java -D... -cp ... main.class.here "$@"
...而不是前面缺少 exec
:
java -D... -cp ... main.class.here "$@"
在前一种情况下,包装器的进程镜像被替换为它调用的 JVM 的进程镜像;在后者中,包装器等待 JVM 退出,然后继续运行。
如果包装器在 JVM 退出后进行任何清理,使用 exec
将阻止这种情况发生,因此会是错误的事情 - 在这种情况下,您会想要包装器在 JVM 运行时仍然存在,否则之后将无法执行清理。
请注意,如果包装器负责分 ionic 进程,则它需要能够关闭打开的文件句柄才能正确执行此操作。如果您的父进程拥有的文件描述符多于仅打开的 stdin、stdout 和 stderr,请考虑将 close_fds=True
传递给您的 Popen 调用。
关于python - 子进程启动两个进程而不是一个,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10297269/