/* file: perthread.c author: Ted Baker version: $Revision$ last modified by: $Author: cop4610 $ on $Date: 2002/09/20 10:13:25 $ purpose: Demonstrate use of pthread_get/setspecific to keep per-thread data. The interesting feature is the procedure print_message(), which is able to print the id of the calling thread, by using pthread_getspecific() to look it up the per-thread data. */ #define _XOPEN_SOURCE 500 #define _REENTRANT #include #include #include #include #define PCHECK(CALL){int result;\ if ((result = (CALL)) != 0) {\ fprintf (stderr, "FATAL: %s (%s)", strerror(result), #CALL);\ exit (-1);}} #define NTHREADS 10 typedef struct perthread_data { int id; } * perthread_data_ptr; pthread_key_t my_key; /* ---------------- my_key_destroy ---------------- This is called by the system whenever a thread dies, to clean up its per-thread data. We tell the system to use this for that purpose when we create the attribute my_key, by passing it to pthread_key_create(), in main(). */ void my_key_destroy (void * arg) { perthread_data_ptr mine = (perthread_data_ptr) arg; fprintf (stderr, "my_key_destroy called for thread %d\n", mine->id); free (mine); } void print_message () { perthread_data_ptr mine = pthread_getspecific (my_key); fprintf (stderr, "This is thread %d\n", mine->id); } void * my_thread_body (void * arg) { int id = (int) arg; perthread_data_ptr mine = (perthread_data_ptr) malloc (sizeof (struct perthread_data)); mine->id = id; PCHECK (pthread_setspecific (my_key, (void *) mine)); print_message (); return NULL; } int main (int argc, char **argv) { pthread_t thread_id[NTHREADS]; int i; PCHECK (pthread_setconcurrency (2)); PCHECK (pthread_key_create (&(my_key), my_key_destroy)); /* The above creates a new per-thread attribute key, and associates it with the "destructor" function my_key_destroy() */ for (i = 1; i < NTHREADS; i++) { PCHECK (pthread_create ( &thread_id[i], /* place to store the id of new thread */ NULL, /* use default thread creation attributes */ my_thread_body, /* function for thread to execute */ (void *) i)); /* pass index of thread */ } for (i = 1; i < NTHREADS; i++) { PCHECK (pthread_join (thread_id[i], NULL)); } exit (0); }