Process.exitValue()和Process.destroy()功能

时间:2012-12-20 12:39:41

标签: java windows process processbuilder

我一直在试验ProcessProcessBuilder并参加此SSCCE。

        import java.io.IOException;
        public class TestProcess {
            public static void main(String[] args) {
                Process process = null;
                ProcessBuilder pb = new ProcessBuilder("notepad.exe");

                try {
                    process = pb.start();
                } catch (IOException e) {e.printStackTrace();}

                //have some time to close notepad
                try {
                    Thread.sleep(10*1000);
                } catch (InterruptedException ignored) {}

                try {
                    System.out.println(process.exitValue());
                 } catch (IllegalThreadStateException e) {
                    System.out.println(e);
                 }

                 if (process != null)
                     process.destroy();

                 /*try {
                     Thread.sleep(0, 1);
                 } catch (InterruptedException ignored) {}*/

                 System.out.println(process.exitValue());
             }
         }
  1. 如果我在10秒超时之前运行此代码并关闭记事本。 destroy()调用在尝试停止已终止的进程时未显示任何问题。的为什么吗
  2. 如果运行此代码并且根本没有关闭记事本(使用注释的第二次睡眠)
  3. 似乎destroy是异步调用(只是发送信号?),导致第二个exitValue()

    异常
     java.lang.IllegalThreadStateException: process has not exited
     Exception in thread "main" java.lang.IllegalThreadStateException: process has not exited
            at java.lang.ProcessImpl.exitValue(ProcessImpl.java:246)
            at TestProcess.main(TestProcess.java:30)
    
    1. 如果我运行此代码并且根本没有关闭记事本(使用未注释的第二次休眠),则第二个exitValue永远不会抛出异常,即使睡眠值仅为1毫秒。 是因为sleep()开销本身吗? 第二个exitValue将返回1.
    2. PS。我从Windows 7和Eclipse运行它。

3 个答案:

答案 0 :(得分:1)

我期望destroy()方法调用本机windows函数TerminateProcess。 看MSDN,我发现了这个:

  

TerminateProcess是异步的;它启动终止并立即返回。如果您需要确保进程已终止,请使用该进程的句柄调用WaitForSingleObject函数。

所以我认为它解释了破坏确实是异步的。

来自同一来源的另一个摘录:

  

TerminateProcess函数用于无条件地导致进程退出。

我想“无条件”可以解释为什么对终止进程的destroy()调用不会失败。

希望这有帮助。 (非常有趣的问题!)

答案 1 :(得分:1)

  1. 为什么显示问题?你正试图摧毁一个已被破坏的进程。 Process.destroy()的规范没有说明如果没有什么可以破坏会发生什么,所以我认为如果没有什么可以破坏那么合乎逻辑(我猜)就没有什么可抱怨的了。与Thread.join()比较,如果线程已经结束,它不会死亡。

  2. 杀死进程的唯一方法是向其发送信号。在某些操作系统上,还有其他更“暴力”的方式(例如,在某些平台上,可以简单地从操作系统的正在运行的进程列表中删除该进程。结果未定义且通常结束很难看),但至少对于我所知道的平台,它实际上就是发送信号。

  3. 确实可能是因为调用Thread.sleep()需要时间。尝试增加超时值。

答案 2 :(得分:1)

ProcessImpl.java方法调用本机函数destroy上的

terminateProcess

public void destroy() { terminateProcess(handle); }

private static native void terminateProcess(long handle);

terminateProcess取决于平台,对于Windows,您可以找到来源here。它只是通过uExitCode=1调用Windows TerminateProcess函数(此函数的链接在以前的答案中,或者你可以google) - 这就是为什么退出的进程代码是1

在linux中看起来像使用类似于this的东西。作为证明,下一个代码在ubuntu中返回143,对应SIGTERMhttps://stackoverflow.com/a/4192488/3181901):

public static void main(final String[] args) throws IOException, InterruptedException {
    final Process process = Runtime.getRuntime().exec(args[0]);
    process.destroy();
    Thread.sleep(1000);
    System.out.println(process.exitValue());
}