2009-06-22 10 views
0

Java 1.6에서 ProcessBuilder를 사용하여 외부 프로세스에서 stdout을 동시에 소비하는 스레드로부터 안전한 방법이 있습니까?외부 프로세스에서 stdout을 동시에 사용합니다.

배경 : 대용량 파일을 stdout에 압축 해제하고 파일이 압축 해제 될 때 각 행을 처리하려면 pbzip2를 호출해야합니다 (pbzip2는 다른 구현과 달리 여러 CPU를 사용함). 그래서

그러나
while((line = reader.readLine()) != null) 
{ 
    // do stuff 
} 

, 압축 풀기가 느린 : 다음과 같이;

논리적 접근 방법은 (? 그냥 이름을 사랑하지 않는 즉, 표준 출력)에의 InputStream을 통해 루프 자식 스레드를 생성하는 것입니다 필자가 정말로 필요로하는 것은 reader.readLine 메소드가 조용히 다음 라인을 종료 할 때까지 기다리는 것이다.

이렇게하는 좋은 방법이 있습니까?

+1

reader.readLine()은 원하는대로 정확하게 수행합니다. 구현이 너무 일찍 종료됩니까? – akarnokd

+0

아니요, 기다렸는지 여부를 지정하지 않은 설명서에서 스레드가 안전한지 궁금합니다. 예를 들어, 타이밍이 방금 발생했다면 readLine은 스트림을 생각할 것인지 닫혀있다. – Rob

답변

2

입력 스트림을 InputStreamReaderBufferedReader으로 감쌀 수 있어야합니다. 그런 다음 readLine()으로 전화를 걸면 필요에 따라 차단됩니다.

stderr에 해당하는 판독기가 있어야합니다. 아무 것도하지 않아도되지만 stderr 스트림을 사용해야합니다. 그렇지 않으면 생성 된 프로세스가 제대로 작동하지 않을 수 있습니다. 링크 등에 대해서는 this answer을 참조하십시오.

1

당신은 솔루션을 더 많이 또는 적게 가지고있을 것입니다. 외부 프로세스의 스트림에서 루프의 다음 행을 읽고 그 행을 처리하는 새로운 스레드를 작성하기 만하면됩니다.

readLine()은 차단하고 새 줄을 모두 사용할 수있을 때까지 대기합니다. 멀티 코어/프로세서 시스템을 사용하는 경우 스레드가 라인을 처리하는 동안 외부 프로세스가 계속 압축 해제를 계속할 수 있습니다. 최소한 압축 풀기는 OS 파이프/버퍼가 가득 찰 때까지 계속 될 수 있습니다.

처리 속도가 압축 해제보다 느리면 압축 해제가 차단되고이 시점에서 메모리 대 속도 문제가 발생합니다. 예 : 당신은 아무것도하지 않고 라인을 읽는 (그래서 압축을 풀지 않을 것입니다) 하나의 스레드를 만들 수 있습니다. 그리고 메모리의 큐에 그들을 버퍼링하고 다른 스레드는 - 또는 심지어 큐를 소비하는 몇몇 스레드를 만듭니다. 전체 라인이 될 때까지

ReadLine 메서드 조용히 대신

에서 종료, 사용할 수있게 위해 다음 라인 (들)을 기다려야 차 그 내의 readLine이 무엇을해야하는지 정확히, 그냥 차단합니다 유효한.

1

예.

나는 (프로세스 빌더에 의해 생성 된) 프로세스에서 시간이 많이 걸리는 작업 (ffmpeg)을 시작하는 몇 가지 코드를 작성했으며, stdio를 소비하는 스레드의 확장 인 내 OutputStreamReader 클래스를 차례로 시작합니다. 그것으로 어떤 마술.

캐치 (나를 위해)가 오류 스트림을 리디렉션하고있었습니다. 다음은 제 코드입니다.

 procbbuilder.redirectErrorStream(true); 
     proc = pb.start(); 
     err = new MyOutputStreamReader(this, proc.getInputStream()); //extenion of thread 
     err.start(); 

     int exitCode = proc.waitFor(); 
관련 문제