如果我通过Runtime.getRuntime().exec(...)
或ProcessBuilder.start()
通过Java获取流程对象,我可以通过Process.waitFor()
等待Thread.join()
,或者我可以杀死它它与Process.destroy()
一样,与弃用的Thread.stop()
类似。
但是:我如何找到过程对象的pid?我没有在The Official Documentation中看到这样做的方法。我可以用Java做到这一点吗?如果是这样,怎么样?
答案 0 :(得分:10)
这家伙呼唤bash获得PID。我不确定是否有解决问题的java解决方案。
/**
* Gets a string representing the pid of this program - Java VM
*/
public static String getPid() throws IOException,InterruptedException {
Vector<String> commands=new Vector<String>();
commands.add("/bin/bash");
commands.add("-c");
commands.add("echo $PPID");
ProcessBuilder pb=new ProcessBuilder(commands);
Process pr=pb.start();
pr.waitFor();
if (pr.exitValue()==0) {
BufferedReader outReader=new BufferedReader(new InputStreamReader(pr.getInputStream()));
return outReader.readLine().trim();
} else {
System.out.println("Error while getting PID");
return "";
}
}
来源: http://www.coderanch.com/t/109334/Linux-UNIX/UNIX-process-ID-java-program
答案 1 :(得分:7)
与上面提到的其他工具类似,Java运行时附带了jps
命令行工具。它会吐出所有正在运行的JVM的PID。好处是需要解析的输出仅限于JVM进程。
答案 2 :(得分:0)
Leo,在研究了这个问题大约一个星期后,我认为Jhurtado的方法可能是我们现在可以用Java管理的“最佳”方法。 “最佳”是引号,因为它具有非常令人讨厌的副作用,基本上是对你的孩子PID的“猜测”。
如果您的Java应用程序在高负载系统中快速生成本机进程,则无法保证您在差异计算中获取的PID是当前线程启动的进程的PID或进程的PID您选择的甚至是我们的应用程序产生的(也许主机系统已经在运行该过程)。
话虽如此,如果你没有产生数十个进程或者你正在产生的本机进程真的是独一无二的(你的应用程序附带了一些自定义工具)那么这种方法可以正常工作,在这种情况下本机进程的PID你正在寻找你想要的那个。
在Windows上你可以使用'任务列表',因为Jhurtado指出要获得所需PID的完整PID列表和过滤器(使用/ FI过滤器开关对我不起作用)测试)。
在任何* nix系统上,你可以使用“ ps ax | grep ”,其中NAME是一些进程名称,例如你要过滤的'nginx'或'httpd'来获取你的列表。< / p>
此外,如果您需要在* nix上杀死杂散进程(例如,在VM退出时),您当然可以使用“ kill -9 ”并在Windows上,有趣的是,您可以使用' taskkill '。
不幸的是,这很难。
答案 3 :(得分:0)
我遇到了和你一样的问题。我找到了一个相当不错的解决方案,我建议稍微睡一觉,以确保该过程正式启动。
Process p = Runtime.getRuntime().exec("cmd /c tasklist");
StringWriter writer = new StringWriter();
IOUtils.copy(p.getInputStream(), writer);
String theString = writer.toString();
//System.out.println(theString);
id = findLastString("javaw.exe .{1,} Console 1", theString);
System.out.println(id);
其中findLastString定义为
public static String findLastString(String pattern, String in) {
Pattern p = Pattern.compile(pattern);
Matcher matcher = p.matcher(in);
String it= "";
while(matcher.find()) {
it = matcher.group();
try {
Thread.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
int firstIndex=pattern.indexOf(".{1,}");
int lastIndex=it.substring(firstIndex).indexOf(pattern.substring(pattern.indexOf(".{1,}")+5))+firstIndex;
String dotOn = it.substring(pattern.indexOf(".{1,}"));
it=it.substring(firstIndex, lastIndex);
return it;
}
基本上这将获得正在运行的进程列表,并找到最近运行的进程,在本例中,名称为javaw.exe(我的程序正在启动一个单独的java进程)。您可以使用任务管理器找到的进程名称替换javaw.exe。您也需要获得Apache通用IO jar。
答案 4 :(得分:-2)
我认为在Java中,最好的方法是在产生子进程之前和之后获得tasklist。制作差异并获得PID。
您可以通过发出Runtime.getRuntime.exec("tasklist");
来获取任务列表
请注意,tasklist.exe不包含在Windows XP Home Edition中,但您仍可以下载它。