Убить процесс с помощью Java - PullRequest
61 голосов
/ 15 июня 2011

Я хотел бы знать, как «убить» запущенный процесс. Мне известно о Process API, но я не уверен, что если я смогу использовать это для «уничтожения» уже запущенного процесса, такого как firefox.exe и т. Д. Если можно использовать Process API, не могли бы вы указать мне на правильное направление? Если нет, каковы другие доступные варианты? Спасибо.

Ответы [ 8 ]

57 голосов
/ 06 июля 2012

В Windows вы можете использовать эту команду.

taskkill /F /IM <processname>.exe 

Чтобы убить его силой, вы можете использовать;

Runtime.getRuntime().exec("taskkill /F /IM <processname>.exe")
51 голосов
/ 15 июня 2011

Если вы запускаете процесс с помощью вашего Java-приложения (например, вызывая Runtime.exec() или ProcessBuilder.start()), тогда у вас есть действительная ссылка Process на него, и вы можете вызвать метод destroy() в Process класс, чтобы убить этот конкретный процесс.

Но имейте в виду, что если вызываемый вами процесс создает новые подпроцессы, они не могут быть завершены (см. http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4770092).

С другой стороны, если вы хотите уничтожить внешние процессы (которые вы не породили в своем Java-приложении), то вы можете просто вызывать утилиты O / S, которые позволяют вам это делать. Например, вы можете попробовать команду Runtime.exec() on kill в Unix / Linux и проверить возвращаемые значения, чтобы убедиться, что приложение было убито или нет (0 означает успех, -1 означает ошибку). Но это, конечно, сделает вашу прикладную платформу зависимой.

30 голосов
/ 15 июня 2011

AFAIU java.lang.Process - процесс, созданный самой java (например, Runtime.exec ('firefox')))

Вы можете использовать системные команды, такие как

 Runtime rt = Runtime.getRuntime();
  if (System.getProperty("os.name").toLowerCase().indexOf("windows") > -1) 
     rt.exec("taskkill " +....);
   else
     rt.exec("kill -9 " +....);
4 голосов
/ 02 июля 2013

Случайно я наткнулся на другой способ принудительного убийства в Unix (для тех, кто использует Weblogic). Это дешевле и элегантнее, чем запускать / bin / kill -9 через Runtime.exec () .

import weblogic.nodemanager.util.Platform;
import weblogic.nodemanager.util.ProcessControl;
...
ProcessControl pctl = Platform.getProcessControl();
pctl.killProcess(pid);

И если вам трудно получить pid, вы можете использовать отражение на java.lang.UNIXProcess , например ::

Process proc = Runtime.getRuntime().exec(cmdarray, envp);
if (proc instanceof UNIXProcess) {
    Field f = proc.getClass().getDeclaredField("pid");
    f.setAccessible(true);
    int pid = f.get(proc);
}
4 голосов
/ 25 апреля 2013

Это может быть дефект интерпретатора java, но java в HPUX не выполняет kill -9, а только kill -TERM.

Я сделал небольшой тест testDestroy.java:

ProcessBuilder pb = new ProcessBuilder(args);
Process process = pb.start();
Thread.sleep(1000);
process.destroy();
process.waitFor();

И вызов:

$ tusc -f -p -s signal,kill -e /opt/java1.5/bin/java testDestroy sh -c 'trap "echo TERM" TERM; sleep 10'

умирает через 10 с (не убивается через 1 с, как ожидалось) и показывает:

...
[19999]   Received signal 15, SIGTERM, in waitpid(), [caught], no siginfo
[19998] kill(19999, SIGTERM) ............................................................................. = 0
...

Выполнение того же в Windows, кажется, нормально завершает процесс, даже если сигнал обрабатывается (но это может быть из-за того, что окна не используют сигналы для уничтожения).

На самом деле я обнаружил Java - исходный код Process.destroy () для Linux связанный поток и реализация openjava, похоже, также используют -TERM, что выглядит очень неправильно.

2 голосов
/ 17 марта 2017

Попробуйте:

String command = "killall <your_proccess>";
Process p = Runtime.getRuntime().exec(command);
p.destroy();

если процесс еще жив, добавьте:

p.destroyForcibly();
1 голос
/ 27 сентября 2018

С Java 9 мы можем использовать ProcessHandle , что упрощает идентификацию и управление собственными процессами:

ProcessHandle
  .allProcesses()
  .filter(p -> p.info().commandLine().map(c -> c.contains("firefox")).orElse(false))
  .findFirst()
  .ifPresent(ProcessHandle::destroy)

где "firefox" - это процесс для уничтожения.

Это:

  • Сначала перечисляются все процессы, запущенные в системе, как Stream<ProcessHandle>

  • Лениво фильтрует этот поток, чтобы сохранить только те процессы, чья запущенная командная строка содержит «firefox». И commandLine, или command могут использоваться в зависимости от того, как мы хотим получить процесс.

  • Находит первый отфильтрованный процесс, удовлетворяющий условию фильтрации.

  • И если хотя бы одна командная строка процесса содержала «firefox», то убивает его, используя destroy.

Импорт не требуется, так как ProcessHandle является частью java.lang.

0 голосов
/ 26 июня 2018

Вы можете уничтожить (SIGTERM) процесс Windows, который был запущен из Java, вызвав метод destroy для объекта Process. Вы также можете убить любые дочерние процессы (начиная с Java 9).

Следующий код запускает пакетный файл, ждет в течение десяти секунд, затем убивает все подпроцессы и, наконец, сам пакетный процесс.

ProcessBuilder pb = new ProcessBuilder("cmd /c my_script.bat"));
Process p = pb.start();
p.waitFor(10, TimeUnit.SECONDS);

p.descendants().forEach(ph -> {
    ph.destroy();
});

p.destroy();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...