2012-06-27 7 views
9

Tengo una aplicación Java donde se crean algunos subprocesos (a través de new Thread()). Utilizando ps puedo ver que tienen diferentes ID de hilo (columna LWP) y me gustaría obtener esos ID desde la aplicación Java.Obtención del ID de subproceso para subprocesos de Java en Linux

En la mayoría de las publicaciones relacionadas con este tema que he encontrado (por ejemplo, this one), la solución es usar ManagementFactory.getRuntimeMXBean().getName().

Usando ese método, sin embargo, me da el PID del hilo principal (incluso si lo llamo desde uno de los hilos), por lo que realmente no está resolviendo mi problema.

¿Hay alguna forma de obtener el ID de hilo para cada Thread creado por una aplicación?

¿Sería posible utilizar JNI para lograrlo? Si de alguna manera pudiera interactuar con una función C donde pudiera llamar al syscall(__NR_gettid), eso podría resolver mi problema. Realmente no me importa la portabilidad, por lo que estoy totalmente de acuerdo con una solución que solo funcionaría para una máquina Linux.

ACTUALIZACIÓN: He resuelto mi problema usando JNI. Los detalles se explican en mi respuesta. Gracias a todos por sus sugerencias/comentarios.

+1

Java rosca pueden no corresponder a un hilo real en el sistema operativo. – nhahtdh

+0

@nhahtdh No estoy 100% seguro de cómo los hilos de Java se correlacionan con los hilos de Linux, pero al menos en mi sistema, tienen un ID de hilo dado como lo hubiera hecho pthread. Como dije, realmente no estoy buscando una solución portátil. – betabandido

+0

@betabandido: Entonces, ¿has intentado implementar esa función JNI?¿O se supone que debemos hacer eso por ti? –

Respuesta

9

Al final, encontré la manera JNI de ser el mejor para resolver mi problema. Como referencia, he puesto el código y las instrucciones de construcción para él (en base a la example en Wikipedia): Clase

Java responsable de interactuar con el código C (GetThreadID.java): archivo

public class GetThreadID { 
    public static native int get_tid(); 

    static { 
     System.loadLibrary("GetThreadID"); 
    } 
} 

C responsable de obtener el ID del hilo (GetThread.c):

#include <jni.h> 
#include <syscall.h> 
#include "GetThreadID.h" 

JNIEXPORT jint JNICALL 
Java_GetThreadID_get_1tid(JNIEnv *env, jobject obj) { 
    jint tid = syscall(__NR_gettid); 
    return tid; 
} 

Un ejemplo de cómo utilizar GetThreadID clase:

class Main { 
    public static void main(String[] args) { 
     int tid = GetThreadID.get_tid(); 
     System.out.println("TID=" + tid); 
    } 
} 

Y, por último, las instrucciones de construcción (javah genera automáticamente GetThreadID.h):

JAVA_HOME=$(readlink -f /usr/bin/javac | sed "s:bin/javac::") 
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:. 
javac GetThreadID.java 
javah GetThreadID 

gcc -I${JAVA_HOME}/include -fPIC -shared GetThreadID.c -o libGetThreadID.so 
javac Main.java 
java Main 
+0

Muy bien, gracias por el seguimiento. Sospeché que no sería demasiado trabajo :) Creo que deberías aceptar tu propia respuesta aquí, ya que definitivamente es la mejor respuesta. –

-2

Si desea identificadores de subprocesos (Id de varios subprocesos que se ejecutan en el Java). Desde su código java, puede llamar al Thread#getId() y colocar los registros requeridos.

Thread.currentThread().getId(); 

Para obtener la ID del proceso puede probar esto. SOURCE

byte[] bo = new byte[100]; 
    String[] cmd = { "bash", "-c", "echo $PPID" }; 
    Process p=null; 
    try { 
     p = Runtime.getRuntime().exec(cmd); 
    } catch (IOException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 
    try { 
     p.getInputStream().read(bo); 
    } catch (IOException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    }  
    System.out.println(new String(bo)); 
+0

Ya probé esto, pero da una ID interna, no la ID de subproceso como lo ve Linux. Por lo tanto, no resuelve mi pregunta. Gracias de cualquier manera. – betabandido

+0

@betabandido He actualizado mi respuesta –

3

This blog post proporciona un método de mapeo de ids de rosca java a ids LWP.

La esencia de esto parece ser que la identificación NLWP se asigna a la identificación del hilo de Java.

+0

Creo que la publicación de blog se refiere a * manualmente * mapeo de los hilos. OP quiere hacerlo automáticamente desde Java –

+0

@NiklasB: Lo sé. Mi punto es que probablemente se puede hacer automáticamente si el OP está dispuesto a asignar los identificadores de subprocesos a la identificación de NLWP en lugar de la ID de LWP. –

+0

@SeanReilly Esto definitivamente parece prometedor. Como dices, podría ser automático. Voy a explorar de esta manera, al igual que el JNI (que sería más directo, pero aún no sé si funcionará). ¡Gracias! – betabandido

Cuestiones relacionadas