Java中的Process Builder和Process - 如何使用超时执行进程: [英] Process Builder and Process in Java - how to execute a process with a timeout :?

查看:1306
本文介绍了Java中的Process Builder和Process - 如何使用超时执行进程:的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要在java中执行具有特定超时的外部批处理文件。这意味着如果批处理执行时间超过指定的超时,我需要取消执行。

I need to execute an external batch file in java with a specific timeout. which means that if the batch execution take longer than specified timeout, i need to cancel the execution.

这里是我写的示例代码:

here is a sample code that i wrote:

public static void main(String[] args) throws IOException, InterruptedException {
    ProcessBuilder p = new ProcessBuilder("c:\\wait.bat", "25");  // batch file execution will take 25 seconds.
    final long l = System.currentTimeMillis();
    System.out.println("starting..." + (System.currentTimeMillis() - l));
    final Process command = p.start();
    System.out.println("started..." + (System.currentTimeMillis() - l));

    Timer t = new Timer();
    t.schedule(new TimerTask() {

        @Override
        public void run() {
            command.destroy();
        }
    }, 5000);   // it will kill the process after 5 seconds (if it's not finished yet).
    int i = command.waitFor();
    t.cancel();
    System.out.println("done..." + (System.currentTimeMillis() - l));
    System.out.println("result : " + i);

    System.out.println("Really Done..." + (System.currentTimeMillis() - l));
}

批处理文件wait.bat是这样的:

the batch file "wait.bat" is something like this:

@echo off
echo starting the process...
@ping 127.0.0.1 -n 2 -w 1000 > nul
@ping 127.0.0.1 -n %1% -w 1000> nul
echo process finished succesfully
@echo on

正如你在代码,批处理文件需要25秒才能完成(主方法中的第一行),定时器将在5秒后销毁命令。

As you see in the code, batch file will take 25 seconds to finish (first line in main method) and the Timer will destroy the command after 5 seconds.

这里是我的代码的输出:

here is the output of my code:

starting...0
started...0
done...5000
result : 1
Really Done...5000
BUILD SUCCESSFUL (total time: 25 seconds)


如你在输出中看到的那样

,最后一行(Really Done ...)在第5秒执行但应用程序在25秒后完成。

as you see in output, the last line ("Really Done...") is executed in 5th second but the application is finished after 25 seconds.

我的问题是:即使我在我的计时器中调用了destroy方法,为什么jvm还在等待进程完成?

my question is that : even though i called the destroy method in my timer, why jvm still waiting for the process to be finished ?

推荐答案

这是 Process.destroy()实现中的rel =nofollow noreferrer> bug 。问题是批处理脚本(或其执行的shell)被终止,但不会杀死它自己的子进程(ping这里)。因此,ping仍然在 .destroy()之后,以及 .waitFor()之后运行。但不知何故,VM仍在等待ping完成之前完成自己。

It is a bug in Java's Process.destroy() implementation on Windows. The problem is that the batch-script (or its executing shell) is killed, but does not kill its own child processes (the ping here). Thus, ping is still running after the .destroy(), and also after the .waitFor(). But somehow the VM still waits for the ping to finish before finishing itself.

似乎没有什么可以从Java端做到这一点来真正可靠地杀死ping。

It seems there is nothing you can do here from the Java side to really kill the ping reliably.

您可以考虑使用 start (在您的批处理脚本或外部)以单独的进程调用ping 。

You may think about using start (in your batch script or outside) to invoke your ping as a separate process.

(另见之前的讨论。)

或者更改为类似unix的操作系统。

Or change to a unix-like operation system.

这篇关于Java中的Process Builder和Process - 如何使用超时执行进程:的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆