首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Process Builder and Process in Java - how to execute a process with a timeout :?

Process Builder and Process in Java - how to execute a process with a timeout :?
EN

Stack Overflow用户
提问于 2011-02-28 14:39:47
回答 3查看 14.8K关注 0票数 5

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

以下是我编写的示例代码:

代码语言:javascript
复制
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“如下所示:

代码语言:javascript
复制
@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秒才能完成( main方法的第一行),而计时器将在5秒后销毁该命令。

以下是我的代码的输出:

代码语言:javascript
复制
starting...0
started...0
done...5000
result : 1
Really Done...5000
BUILD SUCCESSFUL (total time: 25 seconds)

正如您在输出中看到的,最后一行(“真正完成...”)在5秒内执行,但应用程序在25秒后结束。

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

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-03-01 07:06:16

它是Windows上Java的Process.destroy()实现中的一个bug。问题是批处理脚本(或它的执行shell)会被终止,但不会终止它自己的子进程(这里的ping )。因此,ping仍然在.destroy()之后运行,也在.waitFor()之后运行。但不知何故,VM仍在等待ping完成,然后才会自行完成。

在Java端,似乎没有什么可以真正可靠地终止ping。

您可以考虑使用start (在您的批处理脚本中或外部)将ping作为一个单独的进程来调用。

(另请参阅此previous discussion。)

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

票数 8
EN

Stack Overflow用户

发布于 2014-03-04 00:25:51

如果您使用Unix/Linux,那么编写一个包装器bash shell脚本,以便在超时时中断外部命令,然后从Java调用包装器。

包装器脚本如下所示

代码语言:javascript
复制
#!/bin/bash
timeout 60 <your command>

您可以通过检查脚本退出代码来检测是否超时,如果超时,则退出代码为124

看见

手册超时

票数 1
EN

Stack Overflow用户

发布于 2011-02-28 15:17:09

我可能是计时器的cancel方法有问题。尝试将计时器作为守护程序线程启动。

代码语言:javascript
复制
Timer t = new Timer(true);
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5138946

复制
相关文章

相似问题

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