首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Process.exitValue()和Process.destroy()特性

Process.exitValue()和Process.destroy()特性
EN

Stack Overflow用户
提问于 2012-12-20 12:39:40
回答 3查看 25.2K关注 0票数 9

我一直在试验ProcessProcessBuilder,并附带了这个SSCCE。

代码语言:javascript
复制
        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. 如果我在10s超时之前运行此代码并关闭记事本。destroy()调用在试图停止已终止的进程时不会显示任何问题。为什么?
  2. 如果运行此代码而根本不关闭记事本(注释为第二次睡眠)

看来销毁是异步调用(只发送信号?),这会导致第二个exitValue()出现异常。

代码语言:javascript
复制
 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。

PS。我在Windows 7和Eclipse上运行它。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-12-20 13:17:30

  1. 为什么会出现问题呢?你在试图摧毁一个已经被摧毁的过程。Process.destroy()的规范没有说明如果没有要销毁的东西会发生什么,所以(我想)假设如果没有要销毁的东西,那么就没有什么可抱怨的,这是合乎逻辑的(我想)。与Thread.join()相比,它不只是在线程已经结束时就死掉了。
  2. 杀死进程的唯一方法是向它发送一个信号。在某些操作系统上,还有其他更“暴力”的方式(例如,在某些平台上,可以简单地将进程从操作系统运行的进程列表中删除。结果是没有定义的,通常结局很难看),但至少在我所知道的平台上,这一切都是关于发送信号的。
  3. 事实上,有可能是因为调用Thread.sleep()需要时间。尝试增加超时值。
票数 1
EN

Stack Overflow用户

发布于 2015-02-18 19:07:02

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

代码语言:javascript
复制
public void destroy() { terminateProcess(handle); }

private static native void terminateProcess(long handle);

terminateProcess依赖于平台,对于这里,您可以找到源代码。它只是用uExitCode=1调用Windows的TerminateProcess函数(这个函数的链接在以前的答案中,或者你可以搜索它)--这就是为什么被破坏的进程的退出代码是1

在linux中使用的是类似于的东西。下面的代码以ubuntu的形式返回143,对应于SIGTERM (https://stackoverflow.com/a/4192488/3181901):

代码语言:javascript
复制
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());
}
票数 2
EN

Stack Overflow用户

发布于 2012-12-20 13:17:13

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

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

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

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

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

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

希望能帮上忙。(真是有趣的问题!)

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13972442

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档