I’m having trouble getting pthread_equal()
to match stored pthreads. The pthread_t
I get from pthread_self()
seems to be truncated by 4 bytes compared to the one I get from pthread_create()
. Comparisons are in the last code block!
#include <signal.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <netdb.h> #include <unistd.h> #include <arpa/inet.h> #include <netinet/in.h> #include <pthread.h> #include <errno.h> #define QUEUE_SIZE 10 pthread_t *threads_array; int abc; void server_loop(); void *a_loop(void *abc); void printThreadID(pthread_t id); int main(int argc, char **argv) { server_loop(); return 0; } void server_loop() { pthread_t thread_id; threads_array = malloc(QUEUE_SIZE * sizeof(pthread_t)); int i; for (i = 0; i < QUEUE_SIZE; i++) { if (pthread_create(&thread_id, NULL, a_loop, (void*)&abc) < 0) { perror("Thread creation failed"); fprintf(stderr, "Thread creation #%d failedn", i); printThreadID(thread_id); exit(1); } //... store threadID in array fprintf(stderr, "Thread created: "); printThreadID(thread_id); threads_array[i] = thread_id; } sleep(5); } void *a_loop(void *abc) { fprintf(stderr, "@@@@ "); printThreadID(pthread_self()); //... find index of matching pthread_equal(pthread_self(), array[i]) while (1) { } return 0; } // HELPER METHOD void printThreadID(pthread_t id){ size_t i; for (i = sizeof(i); i; --i) fprintf(stderr, "%02x", *(((unsigned char*) &id) + i - 1)); fprintf(stderr, "n"); }
As a result, an attempt to loop through the stored pthreads and compare with pthread_equals fail. Some comparisons (all ten, every time, get truncated the first 4 bytes):
Thread created ID: 00007fda1e402700 self(): 000000001e402700 Thread created ID: 00007fda1dc01700 self(): 000000001dc01700 Thread created ID: 00007fda1cbff700 self(): 000000001cbff700 // Sometimes the zeroes are replaced with ones: Thread created ID: 00007fda1e402700 self(): ffffffff1e402700 Thread created ID: 00007fda1dc01700 self(): ffffffff1dc01700 Thread created ID: 00007fda1cbff700 self(): ffffffff1cbff700
Any idea as to why this is happening?
Advertisement
Answer
this function body is the root of the problem:
size_t i; for (i = sizeof(i); i; --i) { fprintf(stderr, "%02x", *(((unsigned char*) &id) + i - 1)); }
the pthread_t
does not have the same size as an ‘size_t’ and the code is using sizeof(i)
to print the bytes of a pthread_t
. suggest:
for (i = sizeof(pthread_t); i; --i) { fprintf(stderr, "%02x", *(((unsigned char*) &id) + i - 1)); }
although a better method, not using a loop, would be:
fprintf( stderr, "%*x", (int)(2*sizeof(pthread_t)), (int)id );
caveat: the following code does not compile cleanly. It outputs a warning message about the unused parameter abc
So, with a ‘improved’ function: printThreadID()
the program that produced the output is:
#include <signal.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <netdb.h> #include <unistd.h> #include <arpa/inet.h> #include <netinet/in.h> #include <pthread.h> #include <errno.h> #define FROM_CREATE (0) #define FROM_THREAD (1) #define QUEUE_SIZE (10) pthread_t *threads_array; int abc; void server_loop( void ); void *a_loop(void *abc); void printThreadID( int, pthread_t ); int main( void ) { server_loop(); return 0; } void server_loop() { pthread_t thread_id; if( NULL == (threads_array = malloc(QUEUE_SIZE * sizeof(pthread_t)) )) { perror( "malloc for thread array failed" ); exit( EXIT_FAILURE ); } // implied else, malloc successful for (int i = 0; i < QUEUE_SIZE; i++) { if (pthread_create(&thread_id, NULL, a_loop, (void*)&abc) < 0) { perror("Thread creation failed"); fprintf(stderr, "Thread creation #%d failedn", i); printThreadID(FROM_CREATE, thread_id); exit( EXIT_FAILURE ); } // implied else, pthread_create successful //... store threadID in array //fprintf(stderr, "Thread created: "); printThreadID(FROM_CREATE, thread_id); threads_array[i] = thread_id; } sleep(5); } void *a_loop(void *abc) { //fprintf(stderr, "@@@@ "); printThreadID( FROM_THREAD, pthread_self()); //... find index of matching pthread_equal(pthread_self(), array[i]) while (1) { } return 0; } // HELPER METHOD void printThreadID(int fromThread, pthread_t id) { //size_t i; //for (i = sizeof(i); i; --i) //{ // fprintf(stderr, "%02x", *(((unsigned char*) &id) + i - 1)); //} if( FROM_THREAD == fromThread ) { fprintf( stderr, "@@@@ %ldn", (long int)id ); } else { fprintf( stderr, "thread created: %ldn", (long int)id ); } //fprintf(stderr, "n"); }
Here is the output of a typical run of the program, note the exact order of the outputs is depending on which thread wins the race.
thread created: 140506339571456 @@@@ 140506339571456 thread created: 140506331178752 thread created: 140506322786048 thread created: 140506314393344 thread created: 140506306000640 thread created: 140506297607936 thread created: 140506289215232 thread created: 140506280822528 thread created: 140506272429824 thread created: 140506264037120 @@@@ 140506331178752 @@@@ 140506297607936 @@@@ 140506322786048 @@@@ 140506289215232 @@@@ 140506280822528 @@@@ 140506314393344 @@@@ 140506272429824 @@@@ 140506264037120 @@@@ 140506306000640