繁体   English   中英

等待进程和读取流之间的并发问题?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM