Computer >> 컴퓨터 >  >> 프로그래밍 >> Java

Java 9 Process API를 활용해 프로세스의 모든 자식 프로세스 조회하기

Java 9에서는 프로세스 처리(Process Handling) 관련 클래스와 새로운 API가 도입되었습니다. ProcessHandle 인터페이스와 이에 포함된 다양한 메서드를 활용하면 현재 실행 중인 프로세스의 PID뿐만 아니라 다른 관련 프로세스들의 상세 정보도 손쉽게 확인할 수 있습니다.

특정 프로세스의 모든 자식(child) 프로세스를 가져오고 싶다면 java.lang.ProcessHandle.children() 메서드를 사용하면 됩니다. 이 메서드는 해당 프로세스의 자식 프로세스들을 Stream 형태로 반환하며, 만약 자식 프로세스가 존재하지 않는다면 일반적으로 빈 스트림을 반환합니다.

예제 코드

아래 예제에서는 시스템에서 첫 번째 프로세스를 찾은 뒤, 해당 프로세스의 자식 프로세스 정보(PID와 실행 명령어)를 출력하는 방법을 보여줍니다.

import java.util.stream.Stream;
import java.util.Optional;

public class ChildrenProcessTest {
    public static void main(String args[]) throws InterruptedException {
        System.out.println("---------------------------");
        System.out.println("Children Processes:");
        Optional<ProcessHandle> processHandle = ProcessHandle.allProcesses().findFirst();
        processHandle.ifPresent(proc -> proc.children().forEach(
            child -> System.out.println(
                "PID: [ " + child.pid() + " ], Cmd: [ " + child.info().command() + " ]"
            )
        ));
    }
}

실행 결과

---------------------------
Children Processes:
PID: [ 0 ], Cmd: [ Optional.empty ]
PID: [ 4 ], Cmd: [ Optional.empty ]
PID: [ 424 ], Cmd: [ Optional.empty ]
PID: [ 504 ], Cmd: [ Optional.empty ]
PID: [ 560 ], Cmd: [ Optional.empty ]
PID: [ 444 ], Cmd: [ Optional.empty ]
PID: [ 1236 ], Cmd: [ Optional.empty ]
PID: [ 1288 ], Cmd: [ Optional.empty ]
PID: [ 1408 ], Cmd: [ Optional.empty ]
PID: [ 1424 ], Cmd: [ Optional.empty ]
PID: [ 1452 ], Cmd: [ Optional.empty ]
PID: [ 1468 ], Cmd: [ Optional.empty ]
PID: [ 5412 ], Cmd: [ Optional[C:\WINDOWS\System32\taskhostex.exe] ]
PID: [ 3760 ], Cmd: [ Optional[C:\Program Files\Synaptics\SynTP\SynTPEnh.exe] ]
PID: [ 5216 ], Cmd: [ Optional[C:\WINDOWS\explorer.exe] ]
PID: [ 2460 ], Cmd: [ Optional[C:\Program Files (x86)\Dell Wireless\Bluetooth Suite\BtvStack.exe] ]
PID: [ 6064 ], Cmd: [ Optional[C:\Program Files\Realtek\Audio\HDA\RtkNGUI64.exe] ]
PID: [ 7172 ], Cmd: [ Optional[C:\Program Files (x86)\Google\Chrome\Application\chrome.exe] ]
PID: [ 860 ], Cmd: [ Optional[C:\Program Files (x86)\Google\Chrome\Application\chrome.exe] ]
PID: [ 9000 ], Cmd: [ Optional.empty ]
PID: [ 4180 ], Cmd: [ Optional[C:\WINDOWS\System32\cmd.exe] ]
PID: [ 3748 ], Cmd: [ Optional[C:\WINDOWS\System32\conhost.exe] ]
PID: [ 3376 ], Cmd: [ Optional.empty ]
PID: [ 2548 ], Cmd: [ Optional.empty ]
PID: [ 1820 ], Cmd: [ Optional[C:\Program Files\Java\jdk-9.0.4\bin\java.exe] ]

코드 설명

위 코드의 핵심 로직을 단계별로 살펴보면 다음과 같습니다.

1. 전체 프로세스 조회: ProcessHandle.allProcesses() 메서드는 현재 시스템에서 실행 중인 모든 프로세스의 핸들을 스트림으로 반환합니다. 여기에 findFirst()를 호출하여 첫 번째 프로세스 핸들을 Optional<ProcessHandle> 객체로 받아옵니다.

2. 자식 프로세스 순회: ifPresent()를 통해 프로세스 핸들이 실제로 존재하는 경우에만 안전하게 처리를 진행합니다. 이후 children() 메서드가 반환하는 스트림을 forEach()로 순회하며 각 자식 프로세스의 정보를 출력합니다.

3. 프로세스 정보 추출: 각 자식 프로세스에 대해 child.pid()로 프로세스 ID를, child.info().command()로 실행 명령어 경로를 가져옵니다. 명령어 정보는 Optional 타입으로 반환되기 때문에, 접근 권한이 없거나 정보를 얻을 수 없는 프로세스의 경우 Optional.empty가 출력됩니다.

이처럼 Java 9의 Process API를 활용하면 운영체제에 종속적인 네이티브 코드 없이도 순수 Java만으로 프로세스 계층 구조를 탐색하고 관리할 수 있습니다. 프로세스 모니터링 도구나 작업 관리자 유형의 애플리케이션을 개발할 때 매우 유용하게 활용될 수 있습니다.