首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如果外部程序挂起,如何退出进程(.exec())

如果外部程序挂起,如何退出进程(.exec())
EN

Stack Overflow用户
提问于 2013-01-23 15:38:34
回答 1查看 5.9K关注 0票数 4

让我解释一下我的软件。我的软件只是简单地创建了10个线程,并为每个线程分配了许多任务。然后,每个线程创建一个运行时进程,该进程将启动一个cmd批处理文件,然后启动一个程序,该程序将对一个设备(我有大约200个)进行轮询其配置。下面是我创建流程的代码:

代码语言:javascript
运行
复制
Process p1 = java.lang.Runtime.getRuntime().exec("cmd /c  start /b /wait " + batchFile); 
int returnVal = p1.waitFor();

batchFile是批处理文件的完整路径。不要误解我的意思,这个软件的执行效率高达100%,它只在95%的时候挂了一次,所以我想找一个解决方案。为什么它被吊死不是我现在的问题,而是以后如何处理麻烦的问题。

现在的问题是,我需要等待进程完成,因为我的telnet客户端将写入我稍后将在线程中读取的文件;从而使用.waitFor()。我的问题是如何让线程理解外部程序挂起?换句话说,我是否可以给外部程序一些时间限制来完成;如果它不这样做,线程将终止进程?

此外,我还读过关于读取错误和输出流的文章;但是,我认为它不适用于这里,或者它是否适用?

EN

Stack Overflow用户

回答已采纳

发布于 2013-01-23 15:56:32

此外,我还读过关于读取错误和输出流的文章;但是,我认为它不适用于这里,或者它是否适用?

几乎可以肯定的是,它是适用的。尝试使用ProcessBuilder代替Runtime.exec,并在调用waitFor之前读取所有输出。例如(省略异常处理,特别是waitFor可能在进程实际退出之前抛出InterruptedException )

代码语言:javascript
运行
复制
    ProcessBuilder pb = new ProcessBuilder(
        "cmd", "/c", "start", "/b", "/wait", batchFile);
    pb.redirectErrorStream(true);
    Process p = pb.start();
    IOUtils.closeQuietly(p.getOutputStream());
    IOUtils.copy(p.getInputStream(), System.out);
    // or alternatively throw away the output using
    // IOUtils.copy(p.getInputStream(), NullOutputStream.NULL_OUTPUT_STREAM);
    IOUtils.closeQuietly(p.getInputStream());
    int returnVal = p.waitFor();

(IOUtils和NullOutputStream来自Apache commons)。

要回答标题中的实际问题,即使在正确读取输出后,如果进程仍然挂起,则可能需要使用p.destroy()强制终止进程。您可以定义一个计时器任务,比如

代码语言:javascript
运行
复制
    public class TimeoutProcessKiller extends TimerTask {
      private Process p;
      public TimeoutProcessKiller(Process p) {
        this.p = p;
      }

      public void run() {
        p.destroy();
      }
    }

然后再做

代码语言:javascript
运行
复制
    // single shared timer instance
    Timer t = new Timer();

    // for each device
    Process p = pb.start();
    TimerTask killer = new TimeoutProcessKiller(p);
    t.schedule(killer, 30000);
    // ... read output stream as before ...
    int returnVal = p.waitFor();
    killer.cancel();

这将导致进程在运行超过30秒时被终止(调整schedule调用以更改超时)。

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

https://stackoverflow.com/questions/14483397

复制
相关文章

相似问题

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