【问题标题】:How do I find the process ID (pid) of a process started in java? [duplicate]如何找到在 java 中启动的进程的进程 ID (pid)? [复制]
【发布时间】:2011-07-14 03:18:37
【问题描述】:

如果我通过Runtime.getRuntime().exec(...)ProcessBuilder.start()在Java中得到一个进程对象,我可以通过Process.waitFor()等待它,就像Thread.join(),或者我可以用Process.destroy()杀死它,也就是就像已弃用的 Thread.stop()

但是:如何找到进程对象的 pid?我在The Official Documentation 中没有看到这样做的方法。我可以在 Java 中做到这一点吗?如果有,怎么做?

【问题讨论】:

    标签: java process pid


    【解决方案1】:

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

    【讨论】:

    • 另一个好处:它是跨平台的,不像任务列表。
    【解决方案2】:

    这家伙呼叫 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

    【讨论】:

    • 我认为这将给出 JVM 进程的 pid...而不是 Java 产生的进程,我认为这是问题所在。
    • 我认为您需要仔细阅读。它产生一个进程,唯一的工作就是将自己的 PID 回显到其标准输出,而标准输出本身正在管道到与 JVM 关联的标准输入文件描述符。
    • 向量是老式的,并且是同步的 - 不需要使用那种类型的集合 - 尝试使用 ArrayList 代替。只是说。
    • 只是在说什么?这与问题无关。问题是关于访问 PID 而不是 java 最佳实践。
    【解决方案3】:

    我遇到了和你一样的问题。我找到了一个相当不错的解决方案,我建议在它考虑之前稍微休眠以确保进程已正式启动。

    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】:

      Leo,在我自己研究这个问题大约一周后,我认为 Jhurtado 的方法可能是我们现在可以在 Java 中管理的“最佳”方法。 “最好”用引号引起来,因为它具有非常讨厌的副作用,基本上是“猜测”您孩子的 PID 是什么。

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

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

      在 Windows 上,您可以像 Jhurtado 指出的那样使用“tasklist”来获取 PID 的完整列表并过滤您想要的(使用 /FI 过滤器开关不适用于我测试)。

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

      此外,如果您需要在 *nix 上终止杂散进程(例如,在 VM 退出时),您当然可以使用“kill -9 ”,而在 Windows 上,有趣的是,您可以使用'taskkill '。

      不幸的是,几乎不是最优的。

      【讨论】:

        【解决方案5】:

        我认为在 Java 中,您最好的方法是在生成子进程之前和之后获取 tasklist。制作一个差异并获取您的 PID。

        您可以通过发出Runtime.getRuntime.exec("tasklist");获取任务列表
        请注意,tasklist.exe 不包含在 Windows XP 家庭版中,但您仍然可以下载它。

        【讨论】:

        • 你假设我在 Windows 上,但我不是。
        猜你喜欢
        • 2018-02-23
        • 2013-07-03
        • 2017-08-13
        • 1970-01-01
        • 2011-06-12
        • 2014-06-25
        • 2015-06-25
        • 1970-01-01
        相关资源
        最近更新 更多