我如何在Linux上使用Java或JRuby找到我的PID?

13

我需要在Linux平台上找到当前正在运行的进程的PID(可以是系统相关的解决方案)。Java不支持获取进程ID,而JRuby目前在Ruby方法Process.pid方面存在一个bug。

是否还有其他方法可以获得PID?


1
Process.pid在jruby 1.7.23中不再出现问题。 - Jim Davis
6个回答

26
如果你已安装了procfs,你可以通过/proc/self符号链接找到进程ID,该符号链接指向一个名为pid的目录(此处还有其他相关信息的文件,包括PID,但在此情况下只需要目录即可)。
因此,使用Java,您可以执行以下操作:
String pid = new File("/proc/self").getCanonicalFile().getName();

在JRuby中,您可以使用相同的解决方案:
pid = java.io.File.new("/proc/self").canonical_file.name

特别感谢FreeNode上的#stackoverflow频道,帮助我解决问题!(具体来说,JerubgreghTopdeck


7

仅在Linux系统下使用Sun JVM进行测试。可能无法与其他JMX实现一起使用。

String pid = ManagementFactory.getRuntimeMXBean().getName().split("@")[0];

2
您可以使用JNI接口调用POSIX函数getpid()。这很直观。您可以从一个需要的POSIX函数的类开始。我将其称为POSIX.java:
import java.util.*;

class POSIX
{
    static { System.loadLibrary ("POSIX"); }
    native static int getpid ();
}

使用以下命令进行编译:

$ javac POSIX.java

接下来,您需要使用以下命令生成一个名为POSIX.h的头文件:

$ javah -jni POSIX

头文件包含了一个C函数原型,该函数包装了getpid函数。现在你需要实现该函数,这很容易。我在POSIX.c中完成了它:

#include "POSIX.h"

#include <sys/types.h>
#include <unistd.h>

JNIEXPORT jint JNICALL Java_POSIX_getpid (JNIEnv *env, jclass cls)
{
    return getpid ();
}

现在您可以使用gcc进行编译:

$ gcc -Wall -I/usr/lib/jvm/java-1.6.0-sun-1.6.0.21/include -I/usr/lib/jvm/java-1.6.0-sun-1.6.0.21/include/linux -o libPOSIX.so -shared -Wl,-soname,libPOSIX.so POSIX.c -static -lc

您需要指定Java安装的位置。就这些了。现在您可以使用它了。创建一个简单的getpid程序:

public class getpid
{
    public static void main (String argv[])
    {
        System.out.println (POSIX.getpid ());
    }
}

使用javac getpid.java编译它并运行:

$ java getpid &
[1] 21983
$ 21983

第一个pid是由shell编写的,第二个pid是在shell提示返回后由Java程序编写的。∎


2
生成一个shell进程,该进程将读取其父进程的pid。那必须是我们的pid。以下是运行代码,没有例外和错误处理。
import java.io.*;
import java.util.Scanner;

public class Pid2
{
  public static void main(String sArgs[])
    throws java.io.IOException, InterruptedException
  {
    Process p = Runtime.getRuntime().exec(
      new String[] { "sh", "-c", "ps h -o ppid $$" });
    p.waitFor();
    Scanner sc = new Scanner(p.getInputStream());
    System.out.println("My pid: " + sc.nextInt()); 
    Thread.sleep(5000);
  }
}

这个解决方案似乎是最好的,如果PID只需要用来发出另一个shell命令。只需将命令用反引号包裹起来,作为参数传递给另一个命令即可,例如:
nice `ps h -o ppid $$`

这可能会替换给exec调用的数组中的最后一个字符串。


1

Java 9 最终提供了一种官方的方法来使用 ProcessHandle 进行操作:

ProcessHandle.current().pid();

这样做:

  • 首先获取当前进程的ProcessHandle引用。

  • 以便访问其pid

无需导入,因为ProcessHandlejava.lang的一部分。


0

你可以在JNR-Posix中尝试使用getpid()。

它还有一个Windows POSIX包装器,调用libc的getpid()。不需要JNI。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接