当前位置: 首页 > 面试题库 >

Process.waitFor(),线程和InputStreams

楮景明
2023-03-14
问题内容

用伪代码,这是我在做什么:

Process proc = runtime.exec(command);
processOutputStreamInThread(proc.getInputStream());
processOutputStreamInThread(proc.getErrorStream());
proc.waitFor()

但是,有时processOutputStreamInThread看不到任何输出,有时却看到。大致而言,该方法创建BufferedInputStream命令输出的a并将其发送到记录器。

根据我所看到的,我猜,command不用都它的输出排入流美联储getInputStream()getErrorStream(),从而使流是空的。

我的审判结果是以下问题:

(1)waitFor()在java.lang.Process中,是否要求执行程序的输出在返回之前已被读取?

该文档仅说明:

使当前线程在必要时等待,直到此Process对象表示的进程终止。如果子进程已经终止,则此方法立即返回。如果子进程尚未终止,则调用线程将被阻塞,直到子进程退出。

(2) 在什么条件下,由getInputStream和提供的流getErrorStream需要关闭,和/或它们是自动关闭的?

该文档仅说明:

获取子流程的错误流。该流从此Process对象表示的过程的错误输出流中获取通过管道传输的数据。

实施说明:缓冲输入流是个好主意。

一个用户报告说他必须自己关闭流,但是我至少有部分时间遇到异常,表明我尝试关闭流时已经关闭。

编辑: 更改getOutputStreamgetInputStream,现在位于上方。

解决: 问题最终是,在某些情况下,用于处理输出流的线程要到我的短暂进程完成后才能运行,从而导致输入流不提供任何数据。
waitFor没有等待已执行程序的输出。而是,程序可以运行并终止,然后才能收集任何输出。

我使用线程是因为我不确定要在标准错误和标准输出上获得多少输出,并且我希望能够同时处理这两个输出,而不会阻塞一个或另一个,只要其中一个具有可用数据即可。但是,由于我的线程无法始终如一地读取已执行程序的输出,因此这不是解决方案。

我最终的代码看起来像这样:

ProcessBuilder pb = new ProcessBuilder(cmdargs);
pb.redirectErrorStream(true);
Process proc = pb.start();
processOutputStream(proc.getInputStream());
proc.waitFor()

问题答案:

如果您的外部流程期望某些事情stdin,您必须关闭getOutputStream。否则,你将waitFor永远。

这是JavaWorld 的“
何时Runtime.exec()不会提供”一文,其中描述了exec方法的不同陷阱以及如何避免它们。

根据我的经验,最好先消耗子进程的STDOUT和STDERR(直到它们退出EOF),然后再进行阻塞waitFor。希望在这一点上您不必等待很长时间。

Kaleb问题的答案。在正常情况下,您不应该关闭流,但是由于存在这种情况,waitingFor并且由于某种原因它没有超时,如果在输出中遇到某些错误情况并且不想处理子级的流,则可能需要关闭这些流。进一步输出。但是,子程序在另一端关闭STDOUT或STDERR管道时是否终止(崩溃)完全取决于该子程序的实现。但是,大多数Shell程序将在这种情况下终止。

我确实希望waitFor有一些有意义的超时,并且Process在您决定放弃对其进行监视时,有一种记录化的清理资源的方法。



 类似资料:
  • 问题内容: 我正在使用ProcessBuilder类和Process类从Java执行一个.exe文件。解释我在做什么: 我只是想知道,“ waitFor()”等待了多长时间?是等待直到执行我的.exe,还是等到执行完成? 我的.exe是编译好的AutoIt脚本。这意味着,可能需要一些时间才能完成诸如鼠标移动之类的交互。因此,我需要知道在调用.exe之后我的Java代码执行是否继续进行,或者它是否真

  • 主要内容:一、MySql中的线程,二、主要方式,三、源码流程,四、总结一、MySql中的线程 在mysql中,每一个连接上来,就会分配给一个相关的THD数据类。在前面的分析中可以看到,连接器(Connectors)连接到的直接就是连接池,在连接池的线程处理中分为三部分,即一对一(一个连接对应一个线程),多对一(多个连接对应一个线程)和线程池(多对多)。 线程池和线程可以针对不同的具体场景来处理具体的事务,这样既兼顾了效率又提高了适应性,对于新手来说,这就是设计的一个

  • 问题内容: 问题答案: 有很多原因不回来。 但这通常归结为以下事实:执行的命令不会退出。 同样,这可能有很多原因。 一个普遍的原因是该过程产生了一些输出,而你没有从适当的流中读取。这意味着一旦缓冲区已满,进程就会被阻塞,并等待你的进程继续读取。你的进程依次等待另一个进程完成(之所以不会,是因为它等待你的进程,…)。这是一个典型的僵局情况。 你需要不断从流程输入流中读取内容,以确保它不会被阻塞。

  • 线程(thread)是进程(process)中的一个实体,一个进程至少包含一个线程。比如,对于视频播放器,显示视频用一个线程,播放音频用另一个线程。如果我们把进程看成一个容器,则线程是此容器的工作单位。 进程和线程的区别主要有: 进程之间是相互独立的,多进程中,同一个变量,各自有一份拷贝存在于每个进程中,但互不影响;而同一个进程的多个线程是内存共享的,所有变量都由所有线程共享; 由于进程间是独立的

  • Ruby给了你两个基本的方法来组织你的程序,使它同时能运行自己的不同部分。你可以使用线程在程序内部将任务分割,或者将任务分解为不同的程序,使用多进程来运行。下面我们轮流看一下这两种方法。 多线程 一般来说在Ruby中同时做两件事情最简单的是使用Ruby线程。线程在进程中,由Ruby解释器实现。这使得Ruby线程也能完全的可移至,因为它不需要依赖特定的操作系统,但是这样你也不能利用本地线程(nati

  • 很多同学都听说过,现代操作系统比如Mac OS X,UNIX,Linux,Windows等,都是支持“多任务”的操作系统。 什么叫“多任务”呢?简单地说,就是操作系统可以同时运行多个任务。打个比方,你一边在用浏览器上网,一边在听MP3,一边在用Word赶作业,这就是多任务,至少同时有3个任务正在运行。还有很多任务悄悄地在后台同时运行着,只是桌面上没有显示而已。 现在,多核CPU已经非常普及了,但是