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

时间:2022-08-01 07:32:33

This question already has an answer here:

这个问题在这里已有答案:

If I get a process object in Java through Runtime.getRuntime().exec(...), or ProcessBuilder.start(), I can wait for it through Process.waitFor(), which is like Thread.join(), or I could kill it with Process.destroy(), which is like the deprecated Thread.stop().

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

BUT: How do I find the pid of the Process Object? I don't see a method for doing that in The Official Documentation. Can I do this in Java? If so, how?

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

5 个解决方案

#1


10  

This guy calls out to bash to get the PID. I'm not sure if there is an java solution to the problem.

这家伙呼唤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 "";
  }
}

Source: http://www.coderanch.com/t/109334/Linux-UNIX/UNIX-process-ID-java-program

资料来源:http://www.coderanch.com/t/109334/Linux-UNIX/UNIX-process-ID-java-program

#2


7  

Similar to the other tools mentioned, there is the jps command line tool that comes with the Java runtime. It spits out the PIDs of all running JVMs. The benefit is the output one needs to parse is confined to only the JVM processes.

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

#3


0  

Leo, after looking into this issue for about a week myself I think Jhurtado's approach is likely the "best" approach we can manage in Java right now. "best" is in quotes because it has the very nasty side effect of basically being a "guess" at what your child PID is.

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

If your Java app is spawning native processes quickly in a high-load system, there is NO guarantee that the PID you pickup in your diff calculation is the PID of the Process started by the current Thread or that the PID of the process you pick was even spawned by our app (maybe the host system was already running that process anyway).

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

That being said, if you are not spawning dozens of processes or the native Process you are spawning is really unique (some custom util you ship with your app) then this approach works fine in which case the PID of the native process you are looking for is the one you want.

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

On windows you can use 'tasklist' as Jhurtado pointed out to get the full list of PIDs and filter for the one you want (using the /FI filter switch didn't work for me in testing).

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

On any *nix system you can use "ps ax | grep " where NAME is some process name like 'nginx' or 'httpd' that you want to filter for to get your list.

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

Additionally, if you need to kill stray processes (for example, on VM exit) on *nix you can of course use "kill -9 " and on Windows, interestingly enough, you can use 'taskkill '.

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

Hardly optimal unfortunately.

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

#4


0  

I ran into the same issue as you. I found a pretty decent solution, I recommend a slight sleep before it thought to ensure the process has officially started up.

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

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);

where findLastString is defined as

其中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;
 }

Basically this will get the list of running processes, and find the most recently ran one with, in this instance, the name javaw.exe (My program was starting a separate java process). You can replace javaw.exe with the name of the process, which you can find by using Task Manager. You will need to get the Apache common IO jar too.

基本上这将获得正在运行的进程列表,并找到最近运行的进程,在本例中,名称为javaw.exe(我的程序正在启动一个单独的java进程)。您可以使用任务管理器找到的进程名称替换javaw.exe。您还需要获得Apache通用IO jar。

#5


-2  

I think in Java your best shot is to get the tasklist before and after spawning your child process. Make a diff and get your PID.

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

you can get the Tasklist by issuing a Runtime.getRuntime.exec("tasklist");
Notice that tasklist.exe is not included with Windows XP Home edition, but still you can download it.

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

#1


10  

This guy calls out to bash to get the PID. I'm not sure if there is an java solution to the problem.

这家伙呼唤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 "";
  }
}

Source: http://www.coderanch.com/t/109334/Linux-UNIX/UNIX-process-ID-java-program

资料来源:http://www.coderanch.com/t/109334/Linux-UNIX/UNIX-process-ID-java-program

#2


7  

Similar to the other tools mentioned, there is the jps command line tool that comes with the Java runtime. It spits out the PIDs of all running JVMs. The benefit is the output one needs to parse is confined to only the JVM processes.

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

#3


0  

Leo, after looking into this issue for about a week myself I think Jhurtado's approach is likely the "best" approach we can manage in Java right now. "best" is in quotes because it has the very nasty side effect of basically being a "guess" at what your child PID is.

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

If your Java app is spawning native processes quickly in a high-load system, there is NO guarantee that the PID you pickup in your diff calculation is the PID of the Process started by the current Thread or that the PID of the process you pick was even spawned by our app (maybe the host system was already running that process anyway).

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

That being said, if you are not spawning dozens of processes or the native Process you are spawning is really unique (some custom util you ship with your app) then this approach works fine in which case the PID of the native process you are looking for is the one you want.

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

On windows you can use 'tasklist' as Jhurtado pointed out to get the full list of PIDs and filter for the one you want (using the /FI filter switch didn't work for me in testing).

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

On any *nix system you can use "ps ax | grep " where NAME is some process name like 'nginx' or 'httpd' that you want to filter for to get your list.

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

Additionally, if you need to kill stray processes (for example, on VM exit) on *nix you can of course use "kill -9 " and on Windows, interestingly enough, you can use 'taskkill '.

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

Hardly optimal unfortunately.

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

#4


0  

I ran into the same issue as you. I found a pretty decent solution, I recommend a slight sleep before it thought to ensure the process has officially started up.

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

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);

where findLastString is defined as

其中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;
 }

Basically this will get the list of running processes, and find the most recently ran one with, in this instance, the name javaw.exe (My program was starting a separate java process). You can replace javaw.exe with the name of the process, which you can find by using Task Manager. You will need to get the Apache common IO jar too.

基本上这将获得正在运行的进程列表,并找到最近运行的进程,在本例中,名称为javaw.exe(我的程序正在启动一个单独的java进程)。您可以使用任务管理器找到的进程名称替换javaw.exe。您还需要获得Apache通用IO jar。

#5


-2  

I think in Java your best shot is to get the tasklist before and after spawning your child process. Make a diff and get your PID.

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

you can get the Tasklist by issuing a Runtime.getRuntime.exec("tasklist");
Notice that tasklist.exe is not included with Windows XP Home edition, but still you can download it.

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