2008-09-26 1 views
12

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

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

+1

Process.pid больше не работает, по крайней мере, с jruby 1.7.23 – 2016-02-29 18:01:30

ответ

25

Если у вас установлено procfs, вы можете найти идентификатор процесса через/proc/self symlink, который указывает на каталог, имя которого является 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)

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

2

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

Это может substitue последнюю строку в массиве заданного для exec вызова.

0

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

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

Смежные вопросы