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

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

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

Process.pid больше не нарушается, по крайней мере, с jruby 1.7.23

Jim Davis 29.02.2016 21:01
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
13
1
7 242
6
Перейти к ответу Данный вопрос помечен как решенный

Ответы 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 на бесплатном узле за помощь в решении этой проблемы! (в частности, Джеруб, Грег и Верхняя палуба)

Проверено только в 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 после возврата приглашения оболочки. ∎

Создайте процесс оболочки, который будет читать 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.

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

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

ProcessHandle.current().pid();

Этот:

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

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

Импорт не требуется, поскольку ProcessHandle является частью java.lang.

Другие вопросы по теме