2013-10-30 74 views
0

我正在從我的程序中調用一個外部JAVA進程。我消耗由衍生的過程是這樣生成的輸出:ProcessBuilder正在鎖定產生的進程

DataInputStream dis = new DataInputStream(new BufferedInputStream(myProcess.getInputStream())); 

從一個線程我做了以下內容:

  while (dis.available() != 0) 
      {     

       firstMesg = dis.readLine(); 


       if(firstMesg != null) 
       { 
        // processing with the message 
        //System.out.println(firstMesg);  
       }                  
      } 


      try 
      { 
       Thread.currentThread().sleep(SLEEP_TIME); 
      } 
      catch(Throwable e) 
      { 
      } 

我給SLEEP_TIME 1分鐘左右,一切都工作得很好。突然對於特定的設置,我發現Sys(System.out.println)從產生的進程中花費很長時間。

任何人都可以指出我發生了什麼事?這兩個過程必須是獨立的。然而,調用者正在讀取被調用的進程。但是,在被調用的進程正在寫入的地方,緩衝區應該很大。所以沒有辦法阻止它。

我可以在Java的的ProcessBuilder DOC看到這一點:

父進程使用這些流(#getInputStream(),#getErrorStream()),以飼料投入,並從子得到的輸出。由於某些本地平臺 僅爲標準輸入和輸出流提供了有限的緩衝區大小,因此無法及時寫入輸入流或讀取子流程的輸出流可能導致子進程阻塞甚至死鎖。

+0

外部是做什麼的?就像這裏'dis.readLine()'的線程塊一樣''你必須檢查外部進程中發生了什麼。 – Antoniossss

+0

我正在線程上執行此操作,並不斷檢查調用的進程產生了什麼。之間有一個睡眠。 – Exploring

+0

我在考慮外部過程 - 在調用它時調用了一個過程。總之,無論是在主應用程序中等待太久,還是阻止了外部進程,或者進程在生成輸出時都遇到了一些麻煩。總而言之,你不應該這樣等待,但是就像Brian寫的一樣,繼續閱讀流程(這個操作會盡可能地阻擋你)。獲取關於流和流操作的一些信息。 – Antoniossss

回答

0

你需要不斷閱讀,而不是讀取什麼是立即可用,然後睡覺。請注意(也)您應該對stdoutstderr執行相同操作。

有關使用StreamGobbler實現此目的的信息,請參閱this question

+0

如果我繼續閱讀輸出結果,那麼我會被阻止。所以我正在讀什麼可用,然後睡覺和循環。 – Exploring

+0

是的,你被封鎖了。但是你被阻止在你產生的線程上。 *大部分時間*你的stdout和stderr消耗線程將被阻塞,等待你的進程輸出一些東西(除非你的過程確實很冗長) –

+0

我認爲你誤解了這個問題。調用者進程未被阻止。被調用的進程被阻止。 – Exploring

0

這是我期望在你的情況下的行爲。如果一個過程產生stdout(或stderr)輸出,它不能繼續這樣做,如果沒有真正做某件事情的輸出。當你的進程產生輸出時,它將被操作系統緩衝,直到該緩衝區滿了。您的進程從緩衝區讀取,再次創造更多空間。如果你的程序沒有讀取,那麼在某個時候緩衝區將被填滿,操作系統將暫停這個過程直到空間可用。

在您的Java進程中創建一個線程來讀取STDOUT,並在需要時在Java端進行緩衝。另一方面,你應該在它到達時處理它,因爲聽起來好像有很多。

編輯:基於評論...和其他的東西....

DataInputStream.readLine()已過時,不使用它。

而是有一個while循環,做的:

while (dis.available() != 0) {...} 

while ((line = br.readLine()) != null) { ....} 

其中brnew BufferedReader(new InputStreamReader(myProcess.getInputStream()))

+0

他*有一個線程,不是嗎? –

+0

我已經在thread_上執行了這個操作,並且不斷地檢查被調用的進程產生了什麼。在他之間有一個睡眠 – Exploring

+0

他沒有連續檢查過程......他只檢查它,直到沒有可用的第一個時刻。至少當進程啓動時,available()會返回0,這可能會在最初的幾分之一秒內發生,因此,沒有任何東西是從STDOUT中讀取的。考慮在while循環中使用其他條件。 – rolfl

1

看看在NuProcess庫,它提供了無阻塞(異步)用於衍生進程的I/O。 聲明:我是NuProcess的作者。