Как найти мой PID в Java или JRuby на Linux?

Мне нужно найти PID текущего запущенного процесса на платформе Linux (это может быть зависимое системное решение). Java не поддерживает получение идентификатора процесса, и JRuby в настоящее время имеет ошибку с методом Ruby, Process.пид-регулятор.

есть ли другой способ получить PID?

6 ответов


Если у вас procfs установлен, вы можете найти идентификатор процесса через символическую ссылку /proc/self, которая указывает на каталог, имя которого является pid (здесь также есть файлы с другой соответствующей информацией, включая PID, но каталог-это все, что вам нужно в этом случае).

таким образом, с Java, вы можете сделать:

String pid = new File("/proc/self").getCanonicalFile().getName();

в JRuby вы можете использовать одно и то же решение:

pid = java.io.File.new("/proc/self").canonical_file.name

специальные спасибо канал #stackoverflow на свободном узле для помогите мне решить эту проблему! (в частности, Jerub, gregh и сайт topdeck)


тестируется только в Linux с помощью Sun JVM. Может не работать с другими реализациями JMX.

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

вы можете использовать интерфейс 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 написан оболочкой, а второй написан программой Java после того, как приглашение оболочки вернулось. ∎


Spawn процесс оболочки, который будет читать 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 должен быть получен только для выдачи другой команды оболочки. Достаточно обернуть команду в обратные кавычки, чтобы передать ее в качестве аргумента другой команде, например:

nice `ps h -o ppid $$`

Это может заменить последнюю строку в массиве, заданном exec звонок.


вы можете попробовать getpid() в JNR-Posix.

Он также имеет оболочку Windows POSIX, которая вызывает getpid () от libc. Нет необходимости в JNI.


Java 9 наконец предлагает официальный способ сделать это с ProcessHandle:

ProcessHandle.current().pid();

это:

  • сначала получает ProcessHandle ссылка для текущего процесса.

  • для того, чтобы получить доступ к его pid.

нет необходимости импортировать как ProcessHandle является частью java.lang.