/* Thread-specific data example Will Benton CS 537, Summer 2005 */ #include #include #include #include static pthread_key_t tsd_val; void init_key() { /* if you aren't freeing TSD values elsewhere, you'll need to pass in a "destructor function." (If you are freeing them elsewhere, or if your TSD values are all statically allocated, the 2d arg should be NULL.) free() is fine if your TSD values are shallow (things that can be allocated with one call to malloc(), like numbers, character strings, or structs that don't contain pointers), but you'll need a more complex destructor function to deallocate, e.g., a linked list. */ pthread_key_create(&tsd_val, free); } char* get_my_tsd_val() { char *val = (char*)(pthread_getspecific(tsd_val)); return val; } void set_my_tsd_val(char* newval) { pthread_setspecific(tsd_val, (void*)newval); } void* runme(void *arg) { char* my_tsd; set_my_tsd_val((char*)arg); my_tsd = get_my_tsd_val(); fprintf(stderr, "my tsd value is '%s'\n", my_tsd); /* Why do we strdup my_tsd here? The TSD value is destroyed when the thread exits -- so if we want to collect this return value, we need to make a copy. Note that, for project 2, you will not be relying on the return values of thread functions -- just have child threads send a message to the main thread. */ return strdup(my_tsd); } int main(int c, char *v[]) { pthread_t fred, barney; char *wilma, *betty; void *fred_result, *barney_result; wilma = strdup("wilma"); betty = strdup("betty"); init_key(); pthread_create(&fred, NULL, runme, wilma); pthread_create(&barney, NULL, runme, betty); pthread_join(fred, &fred_result); pthread_join(barney, &barney_result); fprintf(stderr, "fred returned '%s' and barney returned '%s'\n", fred_result, barney_result); free(fred_result); free(barney_result); exit(0); }