有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java进程。exitValue()和进程。销毁()功能

我一直在用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. 如果运行此代码并且根本不关闭记事本(带有注释的第二次睡眠)

似乎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永远不会引发异常,即使睡眠值只有1ms这是因为sleep()开销本身吗 第二个exitValue将返回1

另外,我在Windows7和Eclipse上运行它


共 (3) 个答案

  1. # 1 楼答案

    我希望destroy()方法调用本机windows函数TerminateProcess。 看着MSDN,我发现:

    TerminateProcess is asynchronous; it initiates termination and returns immediately. If you need to be sure the process has terminated, call the WaitForSingleObject function with a handle to the process.

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

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

    The TerminateProcess function is used to unconditionally cause a process to exit.

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

    希望这有帮助。(真是个有趣的问题!)

  2. # 2 楼答案

    1. 为什么会显示出问题?你试图破坏一个已经被破坏的进程。Process.destroy()的规范没有说明如果没有要销毁的东西会发生什么,因此(我认为)假设如果没有要销毁的东西,那么就没有什么可抱怨的,这是合乎逻辑的。与Thread.join()相比,如果线程已经结束,它不仅仅会消亡

    2. 终止进程的唯一方法是向其发送信号。在某些操作系统上,还有其他更“暴力”的方式(例如,在某些平台上,可以简单地将进程从操作系统的运行进程列表中删除。结果没有定义,通常结局很糟糕),但至少在我所知的平台上,这实际上是关于发送信号的

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

  3. # 3 楼答案

    ProcessImpl.java关于destroy方法调用本机函数terminateProcess

    public void destroy() { terminateProcess(handle); }
    
    private static native void terminateProcess(long handle);
    

    terminateProcess依赖于平台,对于Windows,您可以找到源代码here。它只是用uExitCode=1调用Windows TerminateProcess函数(指向该函数的链接在前面的答案中,或者你可以用谷歌搜索它)——这就是为什么销毁进程的退出代码是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());
    }