当我在Linux上运行destroy函数来终止java.lang.Process对象(实际上是真正的类型为java.lang.UNIXProcess)时,它会向进程发送一个SIGTERM信号,有没有一种方法可以使用SIGKILL杀死它?
不使用纯Java。
最简单的替代方案是使用Runtime.exec()
作为外部进程运行kill -9 <pid>
命令。
不幸的是,很难获取PID。 你需要使用反射技巧访问private int pid
字段,或者对ps
命令的输出进行处理。
更新 - 实际上,还有另一种方法。创建一个小型工具(C程序、shell脚本等),用于运行真正的外部应用程序。编写该实用程序以便记住子进程的PID,并设置一个SIGTERM信号处理程序来SIGKILL子进程。
Stephen的答案是正确的。我写了和他说的一样:
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虚拟机实现可以选择在返回的名称字符串中嵌入特定于平台的有用信息。”注意:可以选择,这意味着它也可以选择不这样做。而且没有规范说明该信息应如何格式化。 - Stephen Cprocess.pid()
即可获取进程ID。 - Luke Hutchisonpkill
命令。Runtime.getRuntime().exec("pkill firefox").waitFor();
您可以调用destroyForcibly()
方法,该方法默认调用destroy()
方法,但根据Java文档,由ProcessBuilder
或Runtime.exec()
返回的所有子进程都实现了此方法。
destroy()
。请参见此处:https://bugs.openjdk.java.net/browse/JDK-8056139 - Joe
Process.toString()
会产生字符串Process[pid=1234]
。 - Alexander MalakhovtoString()
方法的javadoc没有指定字符串的格式。根据源代码,在Unix上的Oracle Java中,Process
和UnixProcess
的toString()
方法没有从Object.toString()
进行覆盖。你所看到的(最好的情况下)是特定于Android的。 - Stephen C