Description of problem: phthread_self() produces incorrect results Version-Release number of selected component (if applicable): kernel-2.6.9-1.6_FC2 glibc-2.3.3-27.1 How reproducible: I compiled program from http://web.umr.edu/~ercal/284/thread_ex1F.c gcc thread_ex1F.c -lpthread or with -D_REENTRANT after ./a.out /**************************************************************************/ /* PROGRAM DESCRIPTION: */ /* The main() uses thr_create() to create as many as thread_num threads.*/ /* Then the main() waits for the termination of the threads using */ /* thr_join() and displays the message/value returned from two threads. */ /* In the thread routine, it displays the message passed from main() */ /* It also displays the value of a global variable which varies from */ /* 1 to thread_num. At last, thread routine uses thr_exit() to return */ /* an integer to main(). The value of the integer is 2 times the thread */ /* ID. */ /* */ /* During the change/display of the global variable, thr_yield() is */ /* used to cause the current thread to yield its execution to another */ /* thread. */ /* */ /* COMPILATION: gcc -o program program.c -lpthread (*LINUX*) */ /* COMPILATION: gcc -o program program.c -lpthread -lrt (*Solaris*)*/ /**************************************************************************/ #include <stdio.h> #include <stdlib.h> #include <signal.h> #include <sys/types.h> #include <unistd.h> #include <pthread.h> /* POSIX threads */ #define thread_num 4 void *thread_routine(void *); /* prototype of thread routine */ int sharedVar; /* global variable */ int main () { void *pRtnValue; /* pointer to void */ pthread_t tid[thread_num]; /* thread id */ pthread_t departed; /* strings to be passed to threads */ int iValue[thread_num]; int i; /* counter */ sharedVar = 0; signal(SIGALRM, SIG_IGN); for (i = 0; i < thread_num; i++) { iValue[i] = i; } printf("main() process has PID= %d and PPID=%d.\n", getpid(), getppid()); /* create threads with passing strings */ for (i = 0; i < thread_num; i++) { pthread_create(tid + i, NULL, thread_routine, iValue + i ); } for (i = 0; i < thread_num; i++) { ++sharedVar; /* change the value of global variable */ pthread_yield(); /* For Solaris use: sched_yield(); */ } system("ps -acefl | grep ercal"); for (i = 0; i < thread_num; i++) { if( pthread_join(tid[i], &pRtnValue) == 0 ) { /* display the thread id and return value */ printf("main() joined with thread %d with return value %d.\n", tid[i], *(int *)pRtnValue); } else { perror("pthread_join() failure."); exit(1); } } return(0); } void *thread_routine (void *arg) { int pid, i; /* local counter */ /* display the process id */ printf("thread %d has processID= %d and PPID=%d.\n", pthread_self(), getpid(), getppid()); pid = fork(); if ( pid == 0 ) /* child code begins */ { /* display the passed value */ printf("Child (PID=%d) of thread %d received message from main() of %d.\n", getpid(), pthread_self(), *(int *)arg); for (i = 0; i < thread_num; i++) { /* display the value of the global variable */ printf("Child (PID=%d) of thread %d: sharedVar now is %d.\n", getpid(), pthread_self(), sharedVar); pthread_yield(); /* For Solaris use: sched_yield(); */ } printf("Child (PID=%d) of thread %d EXITING .....\n", getpid(), pthread_self()); _exit(0); } if ( pid > 0 ) /* PARENT CODE */ { *(int *)arg = 2 * pthread_self(); /* display the return value */ printf("thread %d (PID=%d) will return an integer of %d.\n", pthread_self(), getpid(), *(int *)arg); /* thread exit with an integer */ pthread_exit (arg); } } I received incorret thread's ID as is shown [cernak@localhost c_programy]$ ./a.out main() process has PID= 2678 and PPID=2581. thread -151090256 has processID= 2678 and PPID=2581. Child (PID=2683) of thread -151090256 received message from main() of 0. Child (PID=2683) of thread -151090256: sharedVar now is 1. thread -151090256 (PID=2678) will return an integer of -302180512. thread -161580112 has processID= 2678 and PPID=2581. Child (PID=2684) of thread -161580112 received message from main() of 1. Child (PID=2684) of thread -161580112: sharedVar now is 1. thread -161580112 (PID=2678) will return an integer of -323160224. thread -172069968 has processID= 2678 and PPID=2581. Child (PID=2685) of thread -172069968 received message from main() of 2. Child (PID=2685) of thread -172069968: sharedVar now is 1. thread -172069968 (PID=2678) will return an integer of -344139936. thread -182559824 has processID= 2678 and PPID=2581. Child (PID=2686) of thread -182559824 received message from main() of 3. Child (PID=2686) of thread -182559824: sharedVar now is 1. thread -182559824 (PID=2678) will return an integer of -365119648. Child (PID=2683) of thread -151090256: sharedVar now is 1. Child (PID=2684) of thread -161580112: sharedVar now is 1. Child (PID=2685) of thread -172069968: sharedVar now is 1. Child (PID=2686) of thread -182559824: sharedVar now is 1. Child (PID=2683) of thread -151090256: sharedVar now is 1. Child (PID=2684) of thread -161580112: sharedVar now is 1. Child (PID=2685) of thread -172069968: sharedVar now is 1. Child (PID=2686) of thread -182559824: sharedVar now is 1. Child (PID=2683) of thread -151090256: sharedVar now is 1. Child (PID=2684) of thread -161580112: sharedVar now is 1. Child (PID=2685) of thread -172069968: sharedVar now is 1. Child (PID=2686) of thread -182559824: sharedVar now is 1. Child (PID=2683) of thread -151090256 EXITING ..... Child (PID=2684) of thread -161580112 EXITING ..... Child (PID=2685) of thread -172069968 EXITING ..... Child (PID=2686) of thread -182559824 EXITING ..... 0 S cernak 2687 2678 TS 21 - 1491 wait 20:07 pts/1 00:00:00 sh -c ps -acefl | grep ercal 0 S cernak 2689 2687 TS 24 - 1129 pipe_w 20:07 pts/1 00:00:00 grep ercal main() joined with thread -151090256 with return value -302180512. main() joined with thread -161580112 with return value -323160224. main() joined with thread -172069968 with return value -344139936. main() joined with thread -182559824 with return value -365119648. [cernak@localhost c_programy]$ I tried more simple program with the same incorret thread ID. I cannot deside what is going wrong. Steps to Reproduce: 1. 2. 3. Actual results: Expected results: Additional info:
Nothing is wrong. pthread_self () returns a pthread_t value. It is a handle for the current thread and it's meaning is completely implementation dependent. For a program, it is just a magic cookie that can be get from pthread_self () or pthread__create, compared with pthread_equal, passed to pthread_join/pthread_detach/pthread_cancel and a couple of other functions. If your program expects it to be small integer, it makes bad assumption. For LinuxThreads it was a small integer, for NPTL it is a pointer, but that's just implementation detail.