程序终止时如何终止通过`exec`运行的进程

7 投票
2 回答
1997 浏览
提问于 2025-04-16 17:33

我有一个Java程序,它会启动另一个Python程序作为一个进程。

Process p = Runtime.getRuntime().exec("program.py", envp);

当Java程序处理完毕时,Python进程也会结束。finish命令会向Python进程发送一个信号,让它关闭。

在正常情况下,进程是这样关闭的:

BufferedWriter output = new BufferedWriter(new OutputStreamWriter(p.getOutputStream()));
output.write("@EOF\n");
output.flush();

但是,当Java程序崩溃时,进程就不会关闭。因为崩溃了,所以没有发送关闭命令。有没有办法让这个进程在每次程序终止时自动结束呢?

2 个回答

3

嘿 @czuk,使用一个ShutdownHook钩子有用吗?这个可以处理以下几种情况:

Java虚拟机会在两种情况下关闭:

  • 程序正常退出,比如最后一个非守护线程结束,或者调用了退出方法(也就是System.exit),

  • 虚拟机因为用户中断而被终止,比如按下了^C,或者因为系统事件,比如用户注销或系统关机。

当系统意外崩溃时,这种情况就不容易捕捉了。

也许可以使用Thread.setDefaultUncaughtExceptionHandler方法?

2

假设你说的崩溃是指Java程序抛出异常,那么我建议在这种情况下直接结束Python进程。我没有看到你的代码,但:

class Foo {

    Process p;

    private void doStuff() throws Exception {
        p = Runtime.getRuntime().exec("program.py", envp);
        // More code ...
    }

    private void startStuff() {
        try {
            doStuff();
        } catch (Exception e) {
            p.destroy();
        }
    }

    public static void main(String[] args) {
        Foo foo = new Foo();
        foo.startStuff();
    }
}

如果只有那些导致程序崩溃的异常从doStuff()中逃出来,这样的做法应该是有效的。

即使你不期望程序在完成时以这种方式崩溃,我认为这种处理方式比把它放在一个外壳脚本中去结束Python进程要好。直接在你的程序中处理这些问题会简单很多,而且在程序完成后保留这段代码也是个好主意,因为你可能还有一些你不知道的bug。

撰写回答