How do I create a global variable that is thread-specific in C using POSIX threads? How do I create a global variable that is thread-specific in C using POSIX threads? multithreading multithreading

How do I create a global variable that is thread-specific in C using POSIX threads?


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 4pthread_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 1Thread 741376 before mod value is 1Thread 3162112 before mod value is 1Thread 3698688 before mod value is 1Thread 2625536 after mod value is 2Thread 741376 after mod value is 2Thread 3162112 after mod value is 2Thread 3698688 after mod value is 2Thread 2625536 before mod value is 2Thread 741376 before mod value is 2Thread 3162112 before mod value is 2Thread 3698688 before mod value is 2Thread 2625536 after mod value is 3Thread 741376 after mod value is 3Thread 3162112 after mod value is 3Thread 3698688 after mod value is 3


In general, what you're looking for is "thread local storage". Here are a few links:

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...