【问题标题】:java - how to kill a Process if it exceeds an alloted timejava - 如果进程超过分配的时间,如何杀死它
【发布时间】:2013-04-09 10:28:57
【问题描述】:

我想知道如果进程超过预定义的时间,最好的方法是检测/杀死进程。我知道一种旧方法是使用 ant 包中的 watchdog/timeoutobserver 类。但是现在已经不推荐使用了,所以我想知道现在应该怎么做?

这是我使用看门狗的代码:

import org.apache.tools.ant.util.Watchdog;
import org.apache.tools.ant.util.TimeoutObserver;


public class executer implements TimeoutObserver {

    private int timeOut = 0;
    Process process = null;
    private boolean killedByTimeout =false;


    public executer(int to) {
        timeOut = t;
    }

    public String executeCommand() throws Exception {
        Watchdog watchDog = null;
        String templine = null;
        StringBuffer outputTrace = new StringBuffer();
        StringBuffer errorTrace = new StringBuffer();



        Runtime runtime = Runtime.getRuntime();



        try {
            //instantiate a new watch dog to kill the process
            //if exceeds beyond the time
            watchDog = new Watchdog(getTimeout());
            watchDog.addTimeoutObserver(this);
            watchDog.start();

            process = runtime.exec(command);

            //... Code to do the execution .....

            InputStream inputStream = process.getInputStream();
            InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
            bufferedReader = new BufferedReader(inputStreamReader);
            while (((templine = bufferedReader.readLine()) != null) && (!processWasKilledByTimeout)) {
                outputTrace.append(templine);
                outputTrace.append("\n");
            }


            this.setStandardOut(outputTrace);


            int returnCode = process.waitFor();
            //Set the return code
            this.setReturnCode(returnCode);

            if (processWasKilledByTimeout) {
                //As process was killed by timeout just throw an exception
                throw new InterruptedException("Process was killed before the waitFor was reached.");
            }


        } finally {
            // stop the watchdog as no longer needed.
            if (aWatchDog != null) {
                aWatchDog.stop();
            }
            try {
                // close buffered readers etc
            } catch Exception() {
            }
            //Destroy process
            //    Process.destroy() sends a SIGTERM to the process. The default action
            //    when SIGTERM is received is to terminate, but any process is free to
            //    ignore the signal or catch it and respond differently.
            //
            //    Also, the process started by Java might have created additional
            //    processes that don't receive the signal at all.
            if(process != null) {

                process.destroy();
            }
        }



        public void timeoutOccured(Watchdog arg0) {
            killedByTimeout = true;

            if (process != null){
                process.destroy();
            }
            arg0.stop();
        }

    }
}

任何帮助将不胜感激,因为我有点失落。我正在尝试将其升级到 Java 7,但如果它挂起超过分配的时间,我还没有掌握杀死它的最佳方法。

谢谢,

【问题讨论】:

  • 向线程发送中断。
  • 以毫秒为单位获取系统时间,经过你想要的时间后,调用finalize();
  • 请明确您的问题:您是在杀死“线程”还是“进程”? (从你的代码看来是后一种,但你问的是误导)

标签: java multithreading timeout runnable


【解决方案1】:

试试

    final Process p = ... 
    Thread t = new Thread() {
        public void run() {
            try {
                Thread.sleep(1000);
                p.destroy();
            } catch (InterruptedException e) {
            }
        };
    };
    p.waitFor();
    t.interrupt();

【讨论】:

  • 这就是我要找的!但是t.start();忘记了。
【解决方案2】:

理论上线程有方法stop() 可以完全杀死线程。从 java 1.1 开始不推荐使用此方法,因为它可能导致资源泄漏。所以,真的不建议你使用它。

“正确”的解决方案是实现您的线程,以便它们在收到特殊“信号”时可以优雅地退出。您可以使用“中断”机制:您的看门狗应该调用超过时间限制的线程的“interrupt()”。但是线程应该自己调用isInterrupted(),如果被中断就退出。好消息是像sleep()wait() 这样的方法已经支持这个,所以如果你的线程正在等待并且你从外部中断它,InterruptedException 将被抛出。

【讨论】:

  • 从示例代码中,我相信OP实际上是要求杀死进程而不是线程。
【解决方案3】:

我写了一组ExecutorServices,它会在给定一定时间执行后取消进程。此代码已签入 GitHub。

用于创建ExecutorService 的类是CancelingExecutors。主要有两个类:

【讨论】:

    【解决方案4】:

    如果你只关心WatchDog本身被废弃了,那么使用TimerTask,过一段时间再做process.destroy(),对你来说并不难。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-06-17
      • 2018-09-12
      • 2016-04-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-01
      • 1970-01-01
      相关资源
      最近更新 更多