【发布时间】:2011-02-26 09:05:32
【问题描述】:
在 Linux 中,当我在 java.lang.Process 对象上运行 destroy 函数(这是真正的类型 java.lang.UNIXProcess )时,它会发送一个 SIGTERM 信号来处理,有没有办法用 SIGKILL 杀死它?
【问题讨论】:
标签: java linux process kill sigterm
在 Linux 中,当我在 java.lang.Process 对象上运行 destroy 函数(这是真正的类型 java.lang.UNIXProcess )时,它会发送一个 SIGTERM 信号来处理,有没有办法用 SIGKILL 杀死它?
【问题讨论】:
标签: java linux process kill sigterm
你可以调用destroyForcibly()方法,它默认调用destroy()方法,但是根据Java文档,ProcessBuilder或Runtime.exec()返回的所有子进程都实现了这个方法。
【讨论】:
destroy()。见这里:bugs.openjdk.java.net/browse/JDK-8056139
如果您知道进程名称,您可以使用pkill
Runtime.getRuntime().exec("pkill firefox").waitFor();
【讨论】:
斯蒂芬他的回答是正确的。我写了他说的:
public static int getUnixPID(Process process) throws Exception
{
System.out.println(process.getClass().getName());
if (process.getClass().getName().equals("java.lang.UNIXProcess"))
{
Class cl = process.getClass();
Field field = cl.getDeclaredField("pid");
field.setAccessible(true);
Object pidObject = field.get(process);
return (Integer) pidObject;
} else
{
throw new IllegalArgumentException("Needs to be a UNIXProcess");
}
}
public static int killUnixProcess(Process process) throws Exception
{
int pid = getUnixPID(process);
return Runtime.getRuntime().exec("kill " + pid).waitFor();
}
您也可以通过这种方式获取 pid:
public static int getPID() {
String tmp = java.lang.management.ManagementFactory.getRuntimeMXBean().getName();
tmp = tmp.split("@")[0];
return Integer.valueOf(tmp);
}
【讨论】:
getName 的 javadoc 说:“返回的名称字符串可以是任意字符串,Java 虚拟机实现可以选择在返回的名称字符串中嵌入特定于平台的有用信息。” 注意:可以选择,表示它也可以选择不。并且没有规范应该如何格式化这些信息。
process.pid() 即可获取进程 ID。
不使用纯 Java。
您最简单的替代方法是使用Runtime.exec() 将kill -9 <pid> 命令作为外部进程运行。
不幸的是,获取 PID 并不是那么简单。您要么需要使用反射黑魔法来访问private int pid 字段,要么会弄乱ps 命令的输出。
更新 - 实际上,还有另一种方法。创建一个小实用程序(C 程序、shell 脚本等)来运行真正的外部应用程序。对实用程序进行编码,使其记住子进程的 PID,并为 SIGTERM 设置一个信号处理程序,该处理程序将 SIGKILL 子进程。
【讨论】:
toString() 方法的 javadoc 没有指定字符串的格式。根据源代码,对于 Unix 上的 Oracle Java,Process 和 UnixProcess 上的 toString() 方法不会被 Object.toString() 覆盖。您所看到的(充其量)是特定于 Android 的。