2013-10-10 2 views
3

Runtime.getRuntime().exec(...)을 사용하여 Windows에서 외부 프로그램을 호출하려고하지만 교착 상태가 발생한 것으로 보입니다. 외부 프로세스는 비동기 적으로 시작되지만 잠시 후 아무 것도하지 않습니다. Java 스레드를 중지하면 외부 프로세스가을 계속하므로 Java 스레드를 기다려야합니다. 현재 관련 코드입니다 :Runtime.getRuntime(). exec (...) 교착 상태가 발생합니다.

try { 
    Process process = Runtime.getRuntime().exec(System.getProperty("user.dir") + "program.exe"); 
    BufferedReader input = new BufferedReader(new InputStreamReader(process.getInputStream())); //Read output of program from its buffer. 
    String line; 
    while((line = input.readLine()) != null) { 
     System.out.println(line); 
    } 
    process.waitFor(); 
} catch(IOException e) { 
    e.printStackTrace(); 
} catch(InterruptedException e) { 
    e.printStackTrace(); 
} 

출력이 3313 바이트가되면 프로그램이 중지됩니다. 버퍼를 비우는 여러 가지 방법을 시도했는데, 때때로이 문제가 발생하기 때문입니다.

외부 프로그램이 완료 될 때까지 Java 프로그램이 대기하고 (process.waitFor()) Java 프로그램을 종료 할 때까지 외부 프로그램이 완료되지 않아 교착 상태가 발생합니다. 어떻게 우리가 이것을 막을 수 있습니까? 우리는 외부 프로그램의 출처에 접근 할 수 없습니다. 외부 프로그램이 완료 될 때까지

답변

2

마지막으로 범인을 찾았습니다. 분명히 런타임 프로세스는 입력 스트림 (Process#getInputStream)뿐만 아니라 오류 스트림 (Process#getErrorStream)을 제공합니다. 외부 프로그램에서 잘못된 형식의 파일에 대한 오류가 발생했기 때문에 오류 스트림도 가득 찼습니다.

솔루션은 별도의 스레드에서 스트림에서 읽는 새로운 실행 가능 클래스를 만드는 것으로 구성됩니다. 그런 다음 주 스레드는이 객체의 두 인스턴스 (입력 스트림에서 읽은 인스턴스와 오류 스트림에서 다른 인스턴스)를 생성 한 다음 두 인스턴스 모두 스레드를 비동기 적으로 실행하게합니다. 이 방법을 사용하면 두 스트림을 동시에 읽었으며 주 스레드는 Process#waitFor을 호출합니다.

나는이 문제에 걸린 사람에게도 도움이되기를 바랍니다.

0

자바 프로그램이 기다리고 (process.waitFor()), 그리고 내가 따라서 교착 상태를 일으키는 원인이되는 자바 프로그램을 종료 때까지 외부 프로그램이 완료되지 않습니다. 이 문제를 방지하려면 어떻게해야합니까? ?

당신은 그것을 막을 수 없습니다. 자바 docs 서브 프로세스가 종료하고 있지 않는 경우

에 따르면, 호출 측 thread는 서브 프로세스가 종료 될 때까지 을 차단됩니다.

관련 문제