当前位置: 首页 > 面试题库 >

强制杀死子进程的Java工具/方法

范凡
2023-03-14
问题内容

我正在寻找一个Java工具/程序包/库,该工具可以强制杀死子进程。

该工具/软件包/库必须在Windows平台上运行(强制性)。需要对Linux / Unix的支持。

我的问题

我的Java代码创建了一个子进程,该子进程不会对杀死子进程的标准Java方法做出反应:process.destroy(),并且由于我没有子进程的源代码,因此我无法对其进行编程以更好地处理终止请求。

我尝试在调用destroy()之前关闭子进程的错误输入和输出流,但没有任何效果。

我什至尝试将ctrlBreak信号(char = 3)直接传递给child.getOutputStream(),并再次收到相同的结果。

我终于设法找到的解决方法是:

  1. 在创建孩子的PID时获取它的PID可以在Windows中通过创建孩子的前后(getRuntime().exec("tasklist /v"))的进程列表进行比较来完成

  2. 在Windows中使用孩子的PID发出强制终止系统命令:getRuntime().exec("taskkill /pid " + childPid + " /f")

但是-这是我不希望调试和维护的复杂代码,而且毫无疑问,许多其他Java开发人员以前都曾遇到过这个问题,这使我希望这样的Java工具/软件包/库已经存在存在。

我只是不知道它的名字…

PS:我的子流程是由创建的Runtime.getRuntime().exec(cmd),但是使用ProcessBuilder会得到相同的行为。


问题答案:

使用Java JNA可以找到一种更精简的方法。

这绝对适用于Windows和Linux,我认为您也可以在其他平台上执行相同的操作。

Java进程处理的最大问题是缺少一种方法来获取以untime.getRuntime()。exec()开始的进程的进程ID。

假设您已获得进程的pid,则始终可以在linux中启动kill -9命令,或使用类似的方法在Windows中终止进程。

这是一种本地获取linux进程ID的方法(从selenium框架中借来的:)),借助JNA,也可以在Windows上完成此操作(使用本地Windows
API调用)。

为此(对于Windows),必须首先从JAVA NATIVE ACCESS(JNA)获得JNA库:下载或从maven获取它。

查看以下代码,该代码将获取(在此示例中为Windows)程序的pid(大多数代码实际上是碎片,以使运行中的java程序正常运行):

import com.sun.jna.*;
import java.lang.reflect.Field;
import java.util.logging.Level;
import java.util.logging.Logger;

public class Main {

static interface Kernel32 extends Library {

    public static Kernel32 INSTANCE = (Kernel32) Native.loadLibrary("kernel32", Kernel32.class);

    public int GetProcessId(Long hProcess);
}

public static void main(String[] args) {
    try {
        Process p;

        if (Platform.isWindows())
            p = Runtime.getRuntime().exec("cmd /C ping msn.de");
        else if (Platform.isLinux())
            p = Runtime.getRuntime().exec("cmd /C ping msn.de");

        System.out.println("The PID: " + getPid(p));

        int x = p.waitFor();
        System.out.println("Exit with exitcode: " + x);

    } catch (Exception ex) {
        Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
    }
}

public static int getPid(Process p) {
    Field f;

    if (Platform.isWindows()) {
        try {
            f = p.getClass().getDeclaredField("handle");
            f.setAccessible(true);
            int pid = Kernel32.INSTANCE.GetProcessId((Long) f.get(p));
            return pid;
        } catch (Exception ex) {
            Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
        }
    } else if (Platform.isLinux()) {
        try {
            f = p.getClass().getDeclaredField("pid");
            f.setAccessible(true);
            int pid = (Integer) f.get(p);
            return pid;
        } catch (Exception ex) {
            Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    else{}
    return 0;
}
}

希望这可以帮助, ;)…



 类似资料:
  • 我得到了一个用java编写的应用程序,它在Unix上运行,并在启动时启动两个子进程(via)。如果应用程序因某种原因崩溃,子进程不会被杀死。 现在,我添加了一个关闭钩子,每次崩溃都会触发它,到目前为止还可以。但是我想在UNIX控制台上为应用程序的每个子进程发送一个SIGTERM信号(或至少SIGINT)。我应该能够通过找到他们的进程ID,但是我没有正确提取PID并为每个进程发送信号。 有人能帮忙吗

  • 问题内容: 我正在python中使用subprocess模块​​运行一些shell脚本。如果shell脚本运行时间很长,我想杀死该子进程。我认为如果将其传递给我的陈述就足够了。 这是代码: 我已经用一些运行120秒的shell脚本测试了此调用。我期望子进程在30秒后被杀死,但是实际上该进程正在完成120秒脚本,然后引发了Timeout Exception。现在的问题是如何通过超时杀死子进程? 问题

  • 问题内容: 我想知道如何“杀死”已启动的过程。我知道Process API,但是不确定,是否可以使用它来杀死已经运行的进程,例如firefox.exe等。如果可以使用Process API,可以请您指向正确的方向?如果没有,还有哪些其他可用选项?谢谢。 问题答案: 如果你从Java应用程序中以从头开始处理(例如,通过调用或),那么你将对其具有有效的引用,并且可以在Process类中调用该方法以终止

  • 问题内容: 我有一个程序生成并与CPU繁重,不稳定的进程通信,而不是由我创建的。如果我的应用程序崩溃或被杀死,我也希望子进程也被杀死,因此用户不必跟踪它们并手动杀死它们。 我知道以前已经讨论过该主题,但是我已经尝试了所有描述的方法,但似乎没有一种方法能够经受住测试的考验。 我知道这是有可能的,因为终端一直在这样做。如果我在终端中运行某些程序并杀死该终端,则这些东西总是会死掉。 我试过了,双叉和。不

  • 问题内容: 我有一个Java应用程序,用于准备操作系统命令并给我一个对象。(实际的os命令是使用cygwin在ssh上进行rsync的)。 这在Windows中运行良好,但是,如果我想停止使用它的进程将不会杀死子ssh和rsync进程……..我必须使用Windows任务管理器手动将其杀死。 是否有可能在我打电话之前以某种方式获取该进程的信息并发送ctrl-c ? 如果有人对解决方法有任何想法,那就

  • 问题内容: 我正在使用child_process.spawn()从在Ubuntu上运行的Node.JS应用程序启动脚本。据我所知,标准的分叉或生成的* nix进程通常不会在父进程死后死亡,但是当从Node.JS生成进程时,它们似乎在我的应用程序崩溃或被ctrl-c等终止时被杀死。 。 为什么会这样,并且有解决办法?我似乎在child_process API中找不到任何明显的选项。 我的应用程序启动