Como faço para encontrar o meu PID em Java ou JRuby no Linux?
Pergunta
Eu preciso encontrar o PID do processo de execução atual em uma plataforma Linux (pode ser uma solução depende do sistema). Java não suportam obter o ID do processo, e JRuby atualmente tem um bug com o método Ruby, Process.pid.
Existe uma outra maneira de obter a PID?
Solução
Se você tiver procfs instalado, você pode encontrar o ID do processo através do / proc / auto ligar simbolicamente, o que aponta para um diretório cujo nome é o pid (há também são arquivos aqui com outras informações pertinentes, incluindo o PID, mas o diretório é tudo que você precisa, neste caso).
Assim, com Java, você pode fazer:
String pid = new File("/proc/self").getCanonicalFile().getName();
Em JRuby, você pode usar a mesma solução:
pid = java.io.File.new("/proc/self").canonical_file.name
Agradecimentos especiais para o canal #stackoverflow no nó livre para me ajudar a resolver isso! (Especificamente, Jerub , gregh e Topdeck )
Outras dicas
Apenas testado em Linux usando Sun JVM. Pode não funcionar com outras implementações JMX.
String pid = ManagementFactory.getRuntimeMXBean().getName().split("@")[0];
Você pode usar a interface JNI para chamar a função POSIX getpid (). É bastante simples. Você começa com uma classe para as funções POSIX que você precisa. Eu chamo-lhe POSIX.java
:
import java.util.*;
class POSIX
{
static { System.loadLibrary ("POSIX"); }
native static int getpid ();
}
compilá-lo com
$ javac POSIX.java
Depois que você gerar um arquivo de cabeçalho POSIX.h
com
$ javah -jni POSIX
O arquivo de cabeçalho contém o protótipo C para a função com wraps a função getpid. Agora você tem que implementar a função, que é bastante fácil. Eu fiz isso em POSIX.c
:
#include "POSIX.h"
#include <sys/types.h>
#include <unistd.h>
JNIEXPORT jint JNICALL Java_POSIX_getpid (JNIEnv *env, jclass cls)
{
return getpid ();
}
Agora você pode compilá-lo 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
Você tem que especificar o local onde o Java está instalado. Isso é tudo. Agora você pode usá-lo. Criar um programa getpid simples:
public class getpid
{
public static void main (String argv[])
{
System.out.println (POSIX.getpid ());
}
}
compilá-lo com javac getpid.java
e executá-lo:
$ java getpid &
[1] 21983
$ 21983
O primeiro pid é escrito pelo shell eo segundo é escrito pelo programa Java após alerta do escudo voltou. ?
gerar um processo shell que irá ler pid do seu pai. Essa deve ser a nossa pid. Aqui está o código em execução, sem exceção e erro de manipulação.
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);
}
}
Esta solução parece ser a melhor se o PID deve ser obtido apenas para emitir outro comando shell. É o suficiente para envolver o comando entre aspas volta para passá-lo como um argumento para outro comando, por exemplo:
nice `ps h -o ppid $$`
Isto pode substitue a última seqüência na matriz dada ao chamado exec
.
Você pode tentar getpid () in JNR-Posix .
Ele também tem um invólucro do Windows POSIX que as chamadas getpid () fora de libc. Sem JNI necessário.
Java 9
finalmente oferece uma maneira oficial de fazê-lo com ProcessHandle :
ProcessHandle.current().pid();
Este:
-
Primeiro obtém uma referência
ProcessHandle
para o processo atual. -
Para acessar a sua
pid
.
No importação necessária como ProcessHandle
faz parte de java.lang
.