Posix Threads unter Linux und deren ID’s

Nach ein paar Monaten Abstinenz von der Welt der POSIX Threads fällt es immer wieder schwer, die ID’s in den richtigen Kontext zu bringen. Deshalb räumt dieser Beitrag nochmal auf.

  • PID/TGID
    Die Process Identification Number ist im Falle von gethreadeden Programmen auch gleichzeitig die Thread Group Identifcation Number. Pro Executable gibt es nur eine solche Nummer, die alle Threads zurückliefern können
  • TID
    Da Linux alle Threads als eigenständige Prozesse (LWP=Lightweight Processes) ansieht, verwaltet der Kernel eine eigene Prozessnummer – die Thread Identication Number. Um den Balanceakt der Unterscheidung zwischen Prozessen und Threads besser zu meistern, kann der Begriff der Kernel Scheduling Entity (KSE) benutzt werden.
  • (Posix) Thread ID
    Diese 32bit Nummer stellt eine eindeutigen POSIX-konformen thread Identifier her. Neben der eigentliche pthreads Verwaltung wird auch in der SW Entwicklung mit den gängigen Tools diese ID gerne benutzt.

Das Einprägen dieser o.g. Definitionen wird einem allerdings durch zahlreiche Monitoring Tools – die sich auf das virtuelle Filesystem proc stützen – nicht gerade erleichert. So zeigen Tools wie htop unter PID eigentlich die TID an. Dafür gibt es einen extra Spalte TGID (welche natürlich das gleiche darstellen sollte als PID). Posix Thread ID fehlt dafür gänzlich.

Eine anschauliche Illustration der Thematik bietet folgendes Programm an:


/*
* gcc -o pthreads_id pthreads_id.c -lpthread
*
* This programs shows the difference of
* 1. The PID (Process ID of the kernel, aka TGID Thread Group ID)
* 2. The TID (Thread ID of the kernel, subsequent number of main threads PID)
* 3. The Posix Thread ID
*/
#include #include
#include
#include
#include

pthread_t ntid;

void printids(const char *s){
pid_t pid;
pid_t tid;
pthread_t ptid;

pid = getpid();
tid = syscall(SYS_gettid);
ptid = pthread_self();
printf("%s pid %u tid %u thread_id %u (0x%x)\n",s,(unsigned int)pid,(unsigned int)tid,(unsigned int)ptid,(unsigned int)ptid);
}

void* thr_fn(void* arg){
printids(" new thread: ");
return((void*)0);
}

int main(void){
int err;
err = pthread_create(&ntid,NULL,thr_fn,NULL);
if(err!=0) printf("can't create thread: %i\n",strerror(err));
printids("main thread: ");
sleep(1);
exit(0);
}

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.