Как уничтожить подпроцессы процесса Java?

#java #process #runtime #runtime.exec

#java #процесс #время выполнения #runtime.exec

Вопрос:

Я создаю процесс P1 с помощью Process P1= Runtime.exec(...) . Мой процесс P1 создает другой процесс, скажем, P2, P3….

Затем я хочу уничтожить процесс P1 и все процессы, созданные P1, т.е. P2, P3…

P1.destroy() уничтожает только P1, а не его подпроцессы.

Я также погуглил это и обнаружил, что это ошибка Java:http://bugs.sun.com/view_bug.do?bug_id=4770092

У кого-нибудь есть идеи о том, как это сделать?

Комментарии:

1. Можете ли вы получить идентификатор процесса подпроцесса? Возможно, вы можете снова уничтожить их с помощью Runtime.exec().

2. По состоянию на 12 мая 2017 года ошибка была закрыта как «Не исправляется». Я предлагаю полагаться на собственные вызовы ОС для закрытия подпроцессов.

Ответ №1:

Да, это ошибка, но если вы прочитаете оценку, основная проблема заключается в том, что практически невозможно реализовать «убить всех маленьких дочерних элементов» в Windows.

Ответ заключается в том, что P1 необходимо отвечать за выполнение собственной очистки.

Ответ №2:

У меня была похожая проблема, когда я запустил процесс PowerShell, который запустил процесс Ping, и когда я остановил свое Java-приложение, процесс PowerShell прекратил бы работу (я бы использовал Process.destroy() для его завершения), но созданный им процесс Ping — нет.

После того, как с ним повозились, этот метод смог выполнить трюк:

 private void stopProcess(Process process) {
    process.descendants().forEach(new Consumer<ProcessHandle>() {
        @Override
        public void accept(ProcessHandle t) {
            t.destroy();
        }
    });
    process.destroy();
}
  

Это убивает данный процесс и все его подпроцессы.

PS: Для использования Process.descendants() метода вам нужна Java 9.

Ответ №3:

Java не предоставляет никакой информации о дочерних процессах по уважительной причине. Если ваш дочерний процесс запускает другой процесс, то управлять ими должен дочерний процесс.

Я бы предложил либо

  • Рефакторинг вашего дизайна таким образом, чтобы ваш родитель создавал / контролировал все дочерние процессы, или
  • Использование команд операционной системы для уничтожения процессов или
  • Используя другой механизм управления, например, некоторую форму межпроцессного взаимодействия (существует множество библиотек Java, предназначенных для этого).

Спасибо @Giacomo за предложение IPC до меня.

Ответ №4:

Вы пишете код других процессов или это то, что вы не можете изменить?

Если вы можете, я бы рассмотрел возможность их модификации таким образом, чтобы они принимали какие-либо сообщения (даже через стандартные потоки), чтобы они красиво завершались по запросу, завершая дочерние процессы, если они есть, самостоятельно.

Я не нахожу этот «уничтожающий процесс» чем-то чистым.

Ответ №5:

если это ошибка, как вы говорите, тогда вы должны отслеживать дерево процессов дочернего процесса и уничтожать все дочерние процессы из дерева, когда вы хотите уничтожить родительский процесс, вам нужно использовать дерево структуры данных для этого, если у вас есть только пара процессов, чем использовать список

Ответ №6:

Поскольку Runtime.exec() возвращает экземпляр процесса, вы можете использовать некоторый массив для хранения их ссылки и уничтожить их позже с помощью Process.destroy().

Комментарии:

1. Вопрос касается процессов, которые являются дочерними по отношению к тому, который выполняется Java