#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