Domanda

Devo trovare il PID dell'attuale processo in esecuzione su una piattaforma Linux (può essere una soluzione dipendente dal sistema). Java non supporta il recupero dell'ID processo e JRuby attualmente ha un bug con il metodo Ruby, Process.pid.

Esiste un altro modo per ottenere il PID?

È stato utile?

Soluzione

Se hai procfs , puoi trovare l'id del processo tramite / proc / self symlink, che punta a una directory il cui nome è il pid (qui ci sono anche file con altre informazioni pertinenti, incluso il PID, ma la directory è tutto ciò che serve in questo caso).

Quindi, con Java, puoi fare:

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

In JRuby, puoi utilizzare la stessa soluzione:

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

Un ringraziamento speciale al canale #stackoverflow sul nodo libero per avermi aiutato a risolvere questo problema! (in particolare, Jerub , gregh e Topdeck )

Altri suggerimenti

Testato solo su Linux usando Sun JVM. Potrebbe non funzionare con altre implementazioni JMX.

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

È possibile utilizzare l'interfaccia JNI per chiamare la funzione POSIX getpid (). È abbastanza semplice. Si inizia con una classe per le funzioni POSIX necessarie. Lo chiamo POSIX.java :

import java.util.*;

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

Compilalo con

$ javac POSIX.java

Successivamente si genera un file di intestazione POSIX.h con

$ javah -jni POSIX

Il file di intestazione contiene il prototipo C per la funzione che racchiude la funzione getpid. Ora devi implementare la funzione, che è abbastanza facile. L'ho fatto in POSIX.c :

#include "POSIX.h"

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

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

Ora puoi compilarlo usando 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

Devi specificare la posizione in cui è installato Java. È tutto. Ora puoi usarlo. Crea un semplice programma getpid:

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

Compilalo con javac getpid.java ed eseguilo:

$ java getpid &
[1] 21983
$ 21983

Il primo pid è scritto dalla shell e il secondo è scritto dal programma Java dopo che è stato restituito il prompt della shell. & # 8718;

Genera un processo shell che leggerà il pid del suo genitore. Questo deve essere il nostro pid. Ecco il codice in esecuzione, senza eccezioni e gestione degli errori.

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);
  }
}

Questa soluzione sembra essere la migliore se il PID deve essere ottenuto solo per emettere un altro comando shell. È sufficiente racchiudere il comando tra virgolette per passare come argomento a un altro comando, ad esempio:

nice `ps h -o ppid $`

Questo può sostituire l'ultima stringa nella matrice data alla chiamata exec .

Puoi provare getpid () in JNR-Posix .

Ha anche un wrapper POSIX per Windows che chiama getpid () fuori da libc. Nessun JNI necessario.

Java 9 offre finalmente un modo ufficiale per farlo con ProcessHandle :

ProcessHandle.current().pid();

Questa:

  • Per prima cosa ottiene un riferimento ProcessHandle per il processo corrente.

  • Per accedere al suo pid.

Nessuna importazione necessaria in quanto ProcessHandle fa parte di java.lang .

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top