in a single thread program. We often use "global variables" to implement shared data among multiple functions, but in a multithreaded environment. Because the data space is shared. Therefore, global variables are also shared by all threads. But sometimes it is necessary in application design to provide thread-Private global variables that are valid only in one thread, but can be interviewed across multiple functions . POSIX line libraries solves the problem by maintaining a certain data structure. This data is called (Thread-specific-data or TSD).
Related functions such as the following:
int Pthread_key_create (pthread_key_t *key, Void (*destr_function) (void *)); int Pthread_key_delete (pthread_key_t key); int pthread_setspecific (pthread_key_t key, const void *pointer); void * Pthread_getspecific (pthread_key_t key); pthread_once_t Once_control = pthread_once_init; int pthread_once (pthread_once_t *once_control, Void (*init_routine) (void));
Watermark/2/text/ahr0cdovl2jsb2cuy3nkbi5uzxqv/font/5a6l5l2t/fontsize/400/fill/i0jbqkfcma==/dissolve/70/gravity /center ">
From the know: when the call to Pthread_key_create will produce a thread-specific data (TSD) key values (such as all of the threads will get a pkey[1] value), but this key point to the real data is different, although it is pkey[1], But instead of pointing to the same piece of memory, they point to the actual data that belongs to them only, so assume that thread 0 changes the data pointed to by pkey[1], and that it does not image to thread n;
After a thread calls Pthread_setspecific, the specific data for each of the threads is bound to thread_key_t, although there is only one pthread_key_t. But the specific data for each thread is a separate memory space, and the destructor function is run when the thread exits.
/** Demo Example 1: Using Pthread_once, let key only initialize once note: The initialization of the key is put into the init_routine **/pthread_key_t key; pthread_once_t Once_control = Pthread_once_init; typedef struct TSD {pthread_t tid; Char *str; } tsd_t; The thread-specific data destruction function,//used to destroy the actual data pointed to by each thread is void destructor_function (void *value) {free (value); cout << "destructor ..." << Endl; }//Initialize function, put the initialization of key into the function,//can guarantee that the Inti_routine function only executes once void Init_routine () {pthread_key_create (&key, Destr Uctor_function); cout << "init ..." << Endl; } void *thread_routine (void *args) {pthread_once (&once_control, init_routine); Set thread-specific data tsd_t *value = (tsd_t *) malloc (sizeof (tsd_t)); Value->tid = Pthread_self (); VALUE->STR = (char *) args; Pthread_setspecific (key, value); printf ("%s setspecific, Address:%p\n", (char *) args, value); Get thread-specific data value = (tsd_t *) pthread_getspecific (key); printf ("tid:0x%x, str =%s\n", (unsigned inT) Value->tid, VALUE->STR); Sleep (2); Get thread-specific data again value = (tsd_t *) pthread_getspecific (key); printf ("tid:0x%x, str =%s\n", (unsigned int) value->tid, value->str); Pthread_exit (NULL); } int main () {pthread_t tid1, Tid2; Pthread_create (&tid1, NULL, Thread_routine, (void *) "thread1"); Pthread_create (&tid2, NULL, Thread_routine, (void *) "thread2"); Pthread_join (TID1, NULL); Pthread_join (Tid2, NULL); Pthread_key_delete (key); return 0; }the results of the execution are as follows:
Init....
Thread1 setspecific, address:0x7fe7a00008c0
tid:0xa8192700, str = thread1
Thread2 setspecific, address:0x7fe7980008c0
tid:0xa7991700, str = thread2
tid:0xa8192700, str = thread1
tid:0xa7001700, str = thread2
destructor ...
destructor ...
The main thread creates two threads and then joins waits for them to exit; the run function for each thread is called pthread_once in thread_routine,thread_routine, and this function represents the assumption that it will run when the first thread calls it Once_ Routine, then returns from Once_routine, which is pthread_once, and no longer runs Once_routine when the other thread that is next calls it. This is to call pthread_key_create only once, which produces a pthread_key_t value.
The type of thread-specific data is defined in the Thread_routine function itself. For different threads, the content of TSD is different, if thread 1 goes to sleep the first time it finishes printing. Thread 2 also starts to run and calls the TSD and key_t of pthread_setspecific bound thread 2, at which time thread 1 calls pthread_getspecific returns the key_t bound TSD pointer, which is still a TSD pointer to thread 1, even though key_t There is only one, but each thread has its own TSD.
Specific data. With the key-value Implementation, a thread creates a keyand other threads are created. but not the same fast memory pointing to. They point to their own data.
This is thread-specific data.
In the above code, even Sleeep (2), thread 1 's data is not affected by thread 2 's data. Because it is thread-private.
When the thread exits, it is destroyed 2 times, due to the creation of two threads.
In addition, about Linux/unix thread private data implementation idea :
Please refer http://blog.csdn.net/caigen1988/article/details/7901248. It's very well written.
Linux multithreading Practice (iv) specific data for threads