java 如何监控 ProcessBuilder 运行的外部进程?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11510409/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 05:23:20  来源:igfitidea点击:

How to monitor external process ran by ProcessBuilder?

javamultithreadingprocess

提问by ?ukaszBachman

This should be rather simple, but I don't see anything helpful in JavaDocs.

这应该相当简单,但我在JavaDocs中看不到任何有用的东西。

What I need is to run some external process from my Java code and then be able to monitor if this process has been shutdown or not. In other words, I want to be able to reliably determine whether or not my external process was not ended by user.

我需要的是从我的 Java 代码运行一些外部进程,然后能够监视该进程是否已关闭。换句话说,我希望能够可靠地确定我的外部进程是否没有被用户终止。

If no cross platform solution exists, I will accept anything working under Linux.

如果不存在跨平台解决方案,我将接受在 Linux 下运行的任何内容。

My current snippet of code:

我当前的代码片段:

public static void main(String[] args) {
    ProcessBuilder pb = new ProcessBuilder("some proces name");

    try {
        Process p = pb.start();
        // p.isRunning(); <- now, that would be helpful :-)
    } catch (IOException e) {
        e.printStackTrace();
    }
}

回答by jtahlborn

Start a new Thread which calls Process.waitFor()and sets a flag when that call returns. then, you can check that flag whenever you want to see if the process has completed.

启动一个新线程,该线程Process.waitFor()在该调用返回时调用并设置一个标志。然后,您可以随时检查该标志以查看该过程是否已完成。

public class ProcMon implements Runnable {

  private final Process _proc;
  private volatile boolean _complete;

  public boolean isComplete() { return _complete; }

  public void run() {
    _proc.waitFor();
    _complete = true;
  }

  public static ProcMon create(Process proc) {
    ProcMon procMon = new ProcMon(proc);
    Thread t = new Thread(procMon);
    t.start();
    return procMon;
  }
}

(some boilerplate omitted).

(省略了一些样板文件)。

回答by Gray

I'm not sure I'm understanding the question but one way to do this is to call process.exitValue();. It throws an exception if process has not yet terminated:

我不确定我是否理解这个问题,但一种方法是调用process.exitValue();. 如果进程尚未终止,则抛出异常:

/**
 * Returns the exit value for the subprocess.
 *
 * @return  the exit value of the subprocess represented by this 
 *          <code>Process</code> object. by convention, the value 
 *          <code>0</code> indicates normal termination.
 * @exception  IllegalThreadStateException  if the subprocess represented 
 *             by this <code>Process</code> object has not yet terminated.
 */
abstract public int exitValue();

If you don't mind a hack, you can do something like the following if you are working on a ~Unix system which uses the UNIXProcessclass. This does use reflection however:

如果您不介意 hack,并且您正在使用UNIXProcess该类的 ~Unix 系统上工作,则可以执行以下操作。然而,这确实使用了反射:

ProcessBuilder pb = new ProcessBuilder("/bin/sleep", "5");
Process process = pb.start();
// open accessability of the UNIXProcess.hasExited field using reflection
Field field = process.getClass().getDeclaredField("hasExited");
field.setAccessible(true);
// now we can get the field using reflection
while (!(Boolean) field.get(process)) {
    ...
}

回答by Harrison Telfer

Based on the question's specific code snippet I might be useful to add that since 1.8 the Processclass has an isAlive()method is available

基于问题的特定代码片段,我可能会补充说,自 1.8 以来,Process该类有一个isAlive()可用的方法

Documentation link: https://docs.oracle.com/javase/8/docs/api/java/lang/Process.html

文档链接:https: //docs.oracle.com/javase/8/docs/api/java/lang/Process.html

good luck to anyone reading this!

祝所有阅读本文的人好运!