Убийство процесса с помощью Java
Я хотел бы знать, как "убить" процесс, который уже запущен. Я знаю о API процесса, но я не уверен, если я могу использовать это, чтобы "убить" уже запущенный процесс, такой как firefox.exe и др. Если процесс API может быть использован, не могли бы вы указать мне в правильном направлении? Если нет, то каковы другие доступные варианты? Спасибо.
8 ответов:
если вы начинаете процесс с помощью вашего Java-приложения (например. позвонив
Runtime.exec()илиProcessBuilder.start()), то у вас есть действительныйProcessссылка на него, и вы можете вызватьdestroy()методProcessкласс, чтобы убить этот конкретный процесс.но имейте в виду, что если процесс, который вы вызываете, создает новые подпроцессы, они не могут быть завершены (см. http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4770092).
С другой стороны, если вы хотите убить внешние процессы (которые вы не породили из своего Java-приложения), тогда одна вещь, которую вы можете сделать, - это вызвать утилиты O/S, которые позволяют вам это сделать. Например, вы можете попробовать
Runtime.exec()onkillкоманда под Unix / Linux и проверьте возвращаемые значения, чтобы убедиться, что приложение было убито или нет (0 означает успех, -1 означает ошибку). Но это, конечно, сделает вашу платформу приложений зависимой.
в Windows вы, вероятно, должны использовать эту команду
taskkill /F /IM <processname>.exeубить его силой. Так и будет
Runtime.getRuntime().exec("taskkill /F /IM <processname>.exe")
AFAIU java.ленг.Процесс-это процесс, созданный самой 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 " +....);
случайно я наткнулся на другой способ сделать force kill на Unix (для тех, кто использует Weblogic). Это дешевле и элегантнее, чем запуск /bin/kill -9 через во время выполнения.exec ().
import weblogic.nodemanager.util.Platform; import weblogic.nodemanager.util.ProcessControl; ... ProcessControl pctl = Platform.getProcessControl(); pctl.killProcess(pid);и если вы боретесь, чтобы получить pid, вы можете использовать отражение на java.ленг.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); }
это может быть дефект интерпретатора 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'умирает после 10s (не убит после 1s, как ожидалось) и показывает:
... [19999] Received signal 15, SIGTERM, in waitpid(), [caught], no siginfo [19998] kill(19999, SIGTERM) ............................................................................. = 0 ...делать то же самое на windows, кажется, убить процесс нормально, даже если сигнал обрабатывается (но это может быть связано с windows, не используя сигналы для уничтожать.)
на самом деле я нашел В Java - Процесс.уничтожить() исходный код для Linux соответствующей теме и реализации openjava, кажется, использовать перспективу, которая, кажется, очень неправильно.
попробуй:
String command = "killall <your_proccess>"; Process p = Runtime.getRuntime().exec(command); p.destroy();Если процесс еще жив, добавьте:
p.destroyForcibly();
вы можете убить (SIGTERM) процесс windows, который был запущен с Java, вызвав метод destroy на объекте процесса. Вы также можете убить любые дочерние процессы (начиная с 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();
С
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.
Comments