如何找到在java中启动的进程的进程ID(pid)?

如果我通过Runtime.getRuntime().exec(...)ProcessBuilder.start()在Java中获取进程对象,我可以通过Process.waitFor()等待它,就像Thread.join() ,或者我可以使用Process.destroy()来杀死它,这与已弃用的Thread.stop()类似。

但是:我如何找到过程对象的pid? 我在官方文档中没有看到这样做的方法。 我可以用Java做到这一点吗? 如果是这样,怎么样?

这家伙呼唤bash获得PID。 我不确定是否有解决问题的java解决方案。

 /** * Gets a string representing the pid of this program - Java VM */ public static String getPid() throws IOException,InterruptedException { Vector commands=new Vector(); 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

与上面提到的其他工具类似,Java运行时附带了jps命令行工具。 它会吐出所有正在运行的JVM的PID。 好处是需要解析的输出仅限于JVM进程。

Leo,在研究了这个问题大约一个星期后,我认为Jhurtado的方法可能是我们现在可以用Java管理的“最佳”方法。 “最佳”是引号,因为它具有非常令人讨厌的副作用,基本上是对你的孩子PID的“猜测”。

如果您的Java应用程序在高负载系统中快速生成本机进程,则无法保证您在差异计算中获取的PID是当前线程启动的进程的PID,或者您选择的进程的PID是甚至由我们的应用程序产生(也许主机系统已经在运行该过程)。

话虽这么说,如果你没有产生数十个进程或产生的本机进程真的是独一无二的(你的应用程序随附的一些自定义工具),那么这种方法可以正常工作,在这种情况下你正在寻找的原生进程的PID是你想要的。

在Windows上你可以使用’ tasklist ‘,因为Jhurtado指出要获得所需的PID的完整列表和filter(使用/ FIfilter开关在测试中对我不起作用)。

在任何* nix系统上,你可以使用“ ps ax | grep ”,其中NAME是一些进程名称,如’nginx’或’httpd’,你想要过滤以获取你的列表。

另外,如果您需要杀死* nix上的迷路进程(例如,在VM退出时),您当然可以使用“ kill -9 ”,而在Windows上,有趣的是,您可以使用“ taskkill ”。

不幸的是,几乎没有最佳。

我遇到了和你一样的问题。 我找到了一个相当不错的解决方案,我建议稍微睡一觉,以确保该过程正式启动。

 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。

我认为在Java中,最好的方法是在产生子进程之前和之后获取任务列表 。 制作差异并获得PID。

您可以通过发出Runtime.getRuntime.exec("tasklist");来获取Tasklist Runtime.getRuntime.exec("tasklist");
请注意,tasklist.exe不包含在Windows XP Home Edition中,但您仍可以下载它。