I am learning about POSIX threads and I have come to the section on Thread Specific Data. The book does an excellent example using a file descriptor. However, I wanted to do the
This is not an answer, but a side note:
If you are working on Linux-specific code, you can use the __thread
keyword. Essentially,
static __thread int counter = 5;
creates a different counter
variable for each thread, initialized to value 5 whenever a new thread gets created. Such code is future-compatible with C11, since C11 standardized the same semantics using the _Thread_local
keyword. This is much saner than the POSIX thread-specific functions (which have implementation-specific limits, and are quite cumbersome compared to the __thread
keyword), on all architectures using C, except those that have declared C99 and later "standard non grata" (i.e., Microsoft).
See the Thread-Local Storage chapter in GCC documentation for details.
The purpose of TLS (thread-local storage) is to provide an defined mechanism whereby code can retrieve thread-specific data stored in a database accessed by a all-threads-known shared key. Your code is storing the same data in TLS: the address of a single global variable). Therefore when a thread requests this data using the tls-key, they will all get back the same address.
I think you intend your code to do something like this:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#define NUMTHREADS 4
pthread_key_t glob_var_key;
void do_something()
{
//get thread specific data
int* glob_spec_var = pthread_getspecific(glob_var_key);
printf("Thread %d before mod value is %d\n", (unsigned int) pthread_self(), *glob_spec_var);
*glob_spec_var += 1;
printf("Thread %d after mod value is %d\n", (unsigned int) pthread_self(), *glob_spec_var);
}
void* thread_func(void *arg)
{
int *p = malloc(sizeof(int));
*p = 1;
pthread_setspecific(glob_var_key, p);
do_something();
do_something();
pthread_setspecific(glob_var_key, NULL);
free(p);
pthread_exit(NULL);
}
int main(void)
{
pthread_t threads[NUMTHREADS];
int i;
pthread_key_create(&glob_var_key,NULL);
for (i=0; i < NUMTHREADS; i++)
pthread_create(threads+i,NULL,thread_func,NULL);
for (i=0; i < NUMTHREADS; i++)
pthread_join(threads[i], NULL);
return 0;
}
Output
Thread 2625536 before mod value is 1
Thread 741376 before mod value is 1
Thread 3162112 before mod value is 1
Thread 3698688 before mod value is 1
Thread 2625536 after mod value is 2
Thread 741376 after mod value is 2
Thread 3162112 after mod value is 2
Thread 3698688 after mod value is 2
Thread 2625536 before mod value is 2
Thread 741376 before mod value is 2
Thread 3162112 before mod value is 2
Thread 3698688 before mod value is 2
Thread 2625536 after mod value is 3
Thread 741376 after mod value is 3
Thread 3162112 after mod value is 3
Thread 3698688 after mod value is 3
In general, what you're looking for is "thread local storage". Here are a few links:
http://publib.boulder.ibm.com/infocenter/iseries/v7r1m0/index.jsp?topic=%2Frzahw%2Frzahwex1.htm
http://en.wikipedia.org/wiki/Thread-local_storage
Choosing pthread_getspecific()
is correct. Here's a good example:
Please review the above example: I think it will point you to the problem ... or suggest a good alternative.
IMHO...