IT TIP

Java를 사용하여 프로세스 종료

itqueen 2020. 11. 29. 12:46
반응형

Java를 사용하여 프로세스 종료


시작된 프로세스를 "종료"하는 방법을 알고 싶습니다. Process API에 대해 알고 있지만 확실하지 않습니다. 이미 실행중인 프로세스 (예 : firefox.exe)를 "종료"하는 데 사용할 수 있다면 Process API를 사용할 수있는 경우 올바른 방향? 그렇지 않은 경우 사용 가능한 다른 옵션은 무엇입니까? 감사.


당신이 당신의 자바 응용 프로그램에서와에서 프로세스를 시작하는 경우 (예. 호출하여 Runtime.exec()또는 ProcessBuilder.start()) 당신은 유효한이 Process그것을 참조를, 당신은 호출 할 수 있습니다 destroy()에 방법을 Process특정 프로세스를 종료하는 클래스입니다.

그러나 호출하는 프로세스가 새 하위 프로세스를 만드는 경우 해당 프로세스가 종료되지 않을 수 있습니다 ( http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4770092 참조 ).

반면에 자바 앱에서 생성하지 않은 외부 프로세스를 종료하려면 할 수있는 한 가지 작업을 수행 할 수있는 O / S 유틸리티를 호출하는 것입니다. 예를 들어 Unix / Linux 에서 Runtime.exec()on kill명령을 시도하고 반환 값을 확인하여 응용 프로그램이 종료되었는지 여부를 확인할 수 있습니다 (0은 성공, -1은 오류). 하지만 물론 그렇게하면 애플리케이션 플랫폼이 종속됩니다.


Windows에서는이 명령을 사용할 수 있습니다.

taskkill /F /IM <processname>.exe 

강제로 죽이려면 다음을 사용할 수 있습니다.

Runtime.getRuntime().exec("taskkill /F /IM <processname>.exe")

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 " +....);

Java 인터프리터 결함 일 수 있지만 HPUX의 java는 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에서 동일한 작업을 수행하면 신호가 처리 되더라도 프로세스가 잘 종료되는 것처럼 보입니다 (그러나 이는 Windows가 신호를 사용하여 파괴하지 않기 때문일 수 있습니다).

실제로 Java-Process.destroy () Linux 관련 스레드 및 openjava 구현에 대한 소스 코드도 -TERM을 사용하는 것으로 보이는데 이는 매우 잘못된 것 같습니다.


우연히 나는 Unix에서 강제 죽이는 다른 방법을 발견했습니다 (Weblogic을 사용하는 사람들을 위해). 이것은 Runtime.exec () 를 통해 / bin / kill -9를 실행하는 것보다 저렴하고 우아 합니다.

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);
}

With Java 9, we can use ProcessHandle which makes it easier to identify and control native processes:

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

where "firefox" is the process to kill.

This:

  • First lists all processes running on the system as a Stream<ProcessHandle>

  • Lazily filters this stream to only keep processes whose launched command line contains "firefox". Both commandLine or command can be used depending on how we want to retrieve the process.

  • Finds the first filtered process meeting the filtering condition.

  • And if at least one process' command line contained "firefox", then kills it using destroy.

No import necessary as ProcessHandle is part of java.lang.


Try it:

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

if the process is still alive, add:

p.destroyForcibly();

You can kill a (SIGTERM) a windows process that was started from Java by calling the destroy method on the Process object. You can also kill any child Processes (since Java 9).

The following code starts a batch file, waits for ten seconds then kills all sub-processes and finally kills the batch process itself.

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();

참고URL : https://stackoverflow.com/questions/6356340/killing-a-process-using-java

반응형