1

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

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

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

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

4

1 回答 1

1

This is actually more of a question about the wrapper than about Python -- you would get the same behavior running it from any other language.

To get the behavior you want, the wrapper would want to have the line where it invokes the JVM look as follows:

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

...as opposed to lacking the exec on front:

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

In the former case, the process image of the wrapper is replaced with that of the JVM it invokes; in the latter, the wrapper waits for the JVM to exit, and then continues to run.

If the wrapper does any cleanup after JVM exit, using exec will prevent this from happening and would thus be the Wrong Thing -- in this case, you would want the wrapper to still exist while the JVM runs, as otherwise it would be unable to perform cleanup afterwards.

Be aware that if the wrapper is responsible for detaching the subprocess, it needs to be able to close open file handles for this to happen correctly. Consider passing close_fds=True to your Popen call if your parent process has more file descriptors than only stdin, stdout and stderr open.

于 2012-04-24T12:03:34.823 回答