2012-06-27 13 views
9

Ho un'applicazione Java in cui sono creati alcuni thread (tramite new Thread()). Usando ps Posso vedere che hanno ID di thread diversi (colonna LWP) e vorrei ottenere quegli ID dall'interno dell'applicazione Java.Ottenimento dell'ID thread per i thread Java in Linux

Nella maggior parte dei post relativi a questo argomento che ho trovato (ad es. this one), la soluzione è utilizzare ManagementFactory.getRuntimeMXBean().getName().

L'utilizzo di tale metodo, tuttavia, mi fornisce il PID del thread principale (anche se lo chiamo da uno dei thread), quindi non risolve il mio problema.

Esiste un modo per ottenere l'ID filo per ogni singolo Thread creato da un'applicazione?

Sarebbe possibile utilizzare JNI per realizzarlo? Se in qualche modo potessi interfacciare con una funzione C in cui potrei chiamare syscall(__NR_gettid), questo potrebbe risolvere il mio problema. Non mi interessa davvero la portabilità, quindi sono assolutamente d'accordo con una soluzione che funzionerebbe solo su una macchina Linux.

UPDATE: Ho effettivamente risolto il problema utilizzando JNI. I dettagli sono spiegati nella mia risposta. Grazie a tutti per i vostri suggerimenti/commenti.

+1

Java Discussione possono non corrispondere a un filo reale sul sistema operativo. – nhahtdh

+0

@nhahtdh Non sono sicuro al 100% in che modo i thread Java si associano ai thread Linux, ma almeno nel mio sistema hanno un determinato ID thread come avrebbe un pthread. Come ho detto, non sto davvero cercando una soluzione portatile. – betabandido

+0

@betabandido: Allora, hai provato a implementare quella funzione JNI?O dovremmo farlo per te? –

risposta

9

Alla fine, ho trovato il modo JNI di essere il migliore per risolvere il mio problema. Come riferimento, ho posto il codice e le istruzioni di compilazione per esso (in base alla example su Wikipedia): class

Java responsabile per interfacciarsi con il codice C (GetThreadID.java): file di

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

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

C responsabile avere la ID filo (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 esempio di come utilizzare GetThreadID classe:

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

E, infine, le istruzioni di costruzione (javah genera automaticamente 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

Molto bello, grazie per il follow-up. Sospettavo che non sarebbe stato troppo lavoro :) Penso che dovresti accettare la tua risposta qui, poiché è sicuramente la migliore risposta. –

-2

Se si desidera l'id di thread (Id di più thread in esecuzione in Java). Dal tuo codice java puoi chiamare lo Thread#getId() e inserire i log richiesti.

Thread.currentThread().getId(); 

Per ottenere l'id di processo è possibile provare questo. 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

Ho già provato questo, ma fornisce un ID interno, non l'ID del thread visto da Linux. Quindi, non risolve la mia domanda. Grazie comunque. – betabandido

+0

@betabandido Ho aggiornato la mia risposta –

3

This blog post fornisce un metodo di mappatura da ids thread Java per ids LWP.

Il nocciolo di esso sembra essere che l'ID NLWP sia associato all'ID del java.

+0

Penso che il post sul blog parli * manualmente * della mappatura dei thread. OP vuole farlo automaticamente da Java –

+0

@NiklasB: lo so. Il mio punto era che probabilmente può essere fatto automaticamente se l'OP è disposto a mappare gli id ​​dei thread in id NLWP invece di LWP id. –

+0

@SeanReilly Questo sembra decisamente promettente. Come stai dicendo, potrebbe essere automatizzato. Esplorerò questo modo, così come il JNI (che sarebbe più diretto, ma non so ancora se funzionerà). Grazie! – betabandido