Завершить процесс запуск с помощью "exec" при завершении программы

у меня есть программа java, которая запускает другую программу (Python) в качестве процесса.

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

Если программа java завершает обработку, процесс Python также завершен. The finish команда отправляет сигнал процессу Python, чтобы закрыть его.

в нормальной ситуации процесс закрывается следующим образом:

BufferedWriter output = new BufferedWriter(new OutputStreamWriter(p.getOutputStream()));
output.write("@EOFn");
output.flush();

однако, когда программа java аварийно завершает работу, процесс не закрыт. Команда закрытия не отправляется из-за сбоя. Возможно ли завершить процессы автоматически каждый раз, когда программа завершается?

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. Обработка его в вашей программе менее сложна, и может быть даже хорошей идеей сохранить код после завершения программы, так как у вас все еще могут быть ошибки, о которых вы не знаете.


Эй @czuk бы ShutdownHook крюк будет какой-либо пользы? Это будет касаться следующих сценариев

виртуальная машина Java завершает работу в ответ на два вида событий:

  • программа завершает работу нормально, когда завершается последний не-демонический поток или когда завершается (эквивалентно, система.exit) вызывается метод, или

  • виртуальная машина завершается в ответ на прерывание пользователя, такое как ввод ^C или a общесистемное событие, такое как выход пользователя или завершение работы системы.

когда система неожиданно падает, это не так просто захватить.

возможно использовать нить.setDefaultUncaughtExceptionHandler способ?