[英]Concurrency issue between waiting for a process and reading the stream?
我使用ProcessBuilder
來運行進程。 我通過提交在線程池( Executors.newCachedThreadPool()
)中處理它們的相應runnable來處理輸入/輸出流。
我得到了結果但是偶爾我什么也得不到。
例如,如果我執行: cmd \\C dir
到進程構建器,我得到dir
的結果,但有時我沒有得到任何東西(盡管結果似乎從處理process.getInputStream
的runnable回來)。
我該怎么調試呢? 它間歇地出現了。 使用相同的代碼,當我執行new Thread(runnable).start()
時,我沒有任何問題。 它在我切換到線程池后開始發生。
更新:
我想我找到了些東西:
我在Runnable
執行以下操作:
try {
while ( (line = br.readLine()) != null) {
pw.println(line);
sb.append(line);
}
System.out.println("Finished reading "+sb.length());
} catch (IOException e) {
e.printStackTrace();
}
finally{
pw.flush();
try{
isr.close();
}catch(Exception e){}
}
在不起作用的情況下,它打印Finished reading 521
。 但我試圖通過pw
得到結果,而不是sb
。
pw
是PrintWriter pw = PrintWriter(outputStream);`我在runnable中傳遞的
更新2:
看來: status = process.waitFor();
在處理輸入流的runnable完成之前返回。 怎么會發生這種情況?
我在javadoc中讀到:
the calling thread will be blocked until the subprocess exits
。 那么這是否意味着我可以在消耗I / O流之前返回?
更新3:
在Ruby中似乎是同樣的問題
即過程結束和消耗輸出之間存在一些競爭條件
是。 進程之間的stdio是緩沖的(通常是4KB緩沖區)。 進程A寫入緩沖區並存在。 進程B有兩個線程; 一個等待A的結束而另一個從A讀取輸出。無法確定哪個線程首先執行。
因此有可能(甚至可能在有大量輸出時) process.waitFor();
在讀取所有緩沖輸出之前返回。
請注意,刷新對此沒有幫助,因為它只是確保A已寫入所有內容。 沒有辦法“強制”B以類似的方式讀取數據。
因此,只有在從輸入流中讀取EOF時,才應記住退出狀態並將該過程視為“完全終止”。
編輯一個解決方案是將waitFor()
移動到流gobbler並將gobbler轉換為Callable
,然后您可以將其提交給執行程序並使用Future
API( 示例 )來獲取結果。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.