Как найти мой 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
.