由Java ProcessBuilder启动的进程没有被破坏

时间:2019-07-17 12:02:29

标签: java cmd process subprocess processbuilder

我正在使用Java ProcessBuilder(JDK 8)。 该过程如下所示。

public Process createProcess(RunnableImplementation runnableImplementation) throws IOException {
    String command = runnableImplementation.command();

    ProcessBuilder processBuilder = new ProcessBuilder();
    processBuilder.directory(new File(runnableImplementation.executionFolderPath()));
    processBuilder.command("cmd.exe", "/c", command);
    processBuilder.redirectErrorStream(true);
    //global var
    process = processBuilder.start();

    return process;
}

我的命令执行一个Ruby脚本,该脚本执行其他Ruby脚本。 当我尝试停止创建的进程时,至少我希望父进程被停止,但事实并非如此。这使我感到困惑,因为以下方法返回true。

public boolean killProcess() {

    System.out.println("Trying to stop the running process, this can take a while");
    boolean success = false;

    if (process != null && process.isAlive()) {
        //global var
        process.destroyForcibly();
        try {
            success = process.waitFor(5, TimeUnit.MINUTES);
            System.out.println("The process was successfully stopped");
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("Waiting for the process to stop was interrupted, it is no longer possible to ensure that all subprocesses are stopped cleanly");
        }
    } else {
        System.out.println("Nothing to stop");

    }
    return success;
}

Process类中的waitFor方法。

    /**
 * Causes the current thread to wait, if necessary, until the
 * subprocess represented by this {@code Process} object has
 * terminated, or the specified waiting time elapses.
 *
 * <p>If the subprocess has already terminated then this method returns
 * immediately with the value {@code true}.  If the process has not
 * terminated and the timeout value is less than, or equal to, zero, then
 * this method returns immediately with the value {@code false}.
 *
 * <p>The default implementation of this methods polls the {@code exitValue}
 * to check if the process has terminated. Concrete implementations of this
 * class are strongly encouraged to override this method with a more
 * efficient implementation.
 *
 * @param timeout the maximum time to wait
 * @param unit the time unit of the {@code timeout} argument
 * @return {@code true} if the subprocess has exited and {@code false} if
 *         the waiting time elapsed before the subprocess has exited.
 * @throws InterruptedException if the current thread is interrupted
 *         while waiting.
 * @throws NullPointerException if unit is null
 * @since 1.8
 */
public boolean waitFor(long timeout, TimeUnit unit)
    throws InterruptedException
{
    long startTime = System.nanoTime();
    long rem = unit.toNanos(timeout);

    do {
        try {
            exitValue();
            return true;
        } catch(IllegalThreadStateException ex) {
            if (rem > 0)
                Thread.sleep(
                    Math.min(TimeUnit.NANOSECONDS.toMillis(rem) + 1, 100));
        }
        rem = unit.toNanos(timeout) - (System.nanoTime() - startTime);
    } while (rem > 0);
    return false;
}

为什么我知道该过程没有停止: 如果通过Windows Cmd启动Ruby进程,则可以看到两个Ruby进程的外观(Windows任务管理器)-如果关闭Cmd窗口或按ctrl + c,它们将消失。当我通过Java启动脚本并执行killProcess方法时,它们不会消失,我必须手动停止它们。

我想停止主流程及其所有子流程,该怎么办?我考虑过跟踪PID。

0 个答案:

没有答案