(1) global variable
(2) Local variables
(3) TSD (thread-specific data thread proprietary)
1.http://upczap.itpub.net/
In a single-threaded program, there are two basic types of data: global variables and local variables. But in multithreaded programs, there is a third type of data: Thread data (tsd:thread-specific). It's very much like a global variable, where each function can call it like a global variable, but it's not visible to other threads outside the thread. The need for such data is obvious. For example, our common variable errno, which returns the standard error message. It obviously cannot be a local variable, almost every function should be able to call it, but it cannot be a global variable, otherwise the output of a thread is likely to be a B-thread error message. To implement such variables, we must use thread data. We create a key for each thread data, it is associated with this key, which is used in each thread to refer to the thread data, but in different threads, the key represents a different data, in the same thread, it represents the same data content.
2.http://bbs.chinaunix.net/viewthread.php?tid=941730
The concept of thread-specific data (thread-related) is introduced into Linux multithreaded programming
Why do I need "thread-related data"? How do I use "thread-related data"?
1. Why do I need to thread-specific data "thread-related"
Here is only one reason I personally think, of course it has many other uses, welcome to discuss
Example: the implementation runs two threads at the same time, for each thread, the name of the thread is printed in each function that the thread calls, and the name of the function it is calling.
(The following examples and implementations are just to illustrate the problem, some may be inappropriate)
Two implementations of "thread-related data" are not used:
Implementation Method 1. Do not use global variables #include <string.h>
#include <pthread.h>
#define MAXLENGTH 20
void Another_func (const char * threadname)
{
printf ("%s is running in another_func/n", threadname);
}
void * Thread_func (void * args)
{
Char Threadname[maxlength];
strncpy (ThreadName, (char *) args, MAXLENGTH-1);
printf ("%s is running in thread_func/n", threadname);
Another_func (ThreadName);
}
int main (int argc, char * argv[])
{
pthread_t PA, PB;
Pthread_create (&pa, NULL, Thread_func, "thread A");
Pthread_create (&PB, NULL, Thread_func, "thread B");
Pthread_join (PA, NULL);
Pthread_join (Pb, NULL);
}
The output results are:
Thread A is running in Thread_func
Thread A is running in Another_func
Thread B is running in Thread_func
Thread B is running in Another_func
The disadvantage of this method is that, because to record which thread is calling the function, each function requires an extra parameter to
Record the name of the thread, such as the Another_func function requires a threadname parameter
If more functions are called, each requires one of these parameters
Implementation Method 2. Using Global variables #include <string.h>
#include <pthread.h>
#define MAXLENGTH 20
Char Threadname[maxlength];
pthread_mutex_t Sharedmutex=pthread_mutex_initializer;
void Another_func ()
{
printf ("%s is running in another_func/n", threadname);
}
void * Thread_func (void * args)
{
Pthread_mutex_lock (&sharedmutex);
strncpy (ThreadName, (char *) args, MAXLENGTH-1);
printf ("%s is running in thread_func/n", threadname);
Another_func ();
Pthread_mutex_unlock (&sharedmutex);
}
int main (int argc, char * argv[])
{
pthread_t PA, PB;
Pthread_create (&pa, NULL, Thread_func, "thread A");
Pthread_create (&PB, NULL, Thread_func, "thread B");
Pthread_join (PA, NULL);
Pthread_join (Pb, NULL);
}
The disadvantage of this method is that because multiple threads need to read and write the global variable threadname, they need to use the mutex mechanism
Analyzing the above two implementations, one of the benefits of THREAD-SPECIFIC data "thread-related" shows:
(1) "Thread-related data" can be a global variable, and
(2) "Thread-related data" accessed by each thread is independent of each other.
2. How to use "thread-related data"
This is how thread-related data is implemented: #include <string.h>
#include <pthread.h>
pthread_key_t P_key;
void Another_func ()
{
printf ("%s is running in another_func/n", (char *) pthread_getspecific (P_key));
}
void * Thread_func (void * args)
{
Pthread_setspecific (P_key, args);
printf ("%s is running in thread_func/n", (char *) pthread_getspecific (P_key));
Another_func ();
}
int main (int argc, char * argv[])
{
pthread_t PA, PB;
Pthread_key_create (&p_key, NULL);
Pthread_create (&pa, NULL, Thread_func, "thread A");
Pthread_create (&PB, NULL, Thread_func, "thread B");
Pthread_join (PA, NULL);
Pthread_join (Pb, NULL);
}
Description
(1)
Thread A, B shared the P_key,
With P_key, you can access a value that is related only to the current thread (this value is managed by the compiler)
Thread A----->p_key-----> Thread A-related values (managed by the compiler)
Thread B----->p_key-----> Thread B-related values (managed by the compiler)
Set "thread-related data" to use the
int pthread_setspecific (pthread_key_t key, const void *pointer);
Read "Thread-related data", using the
void * Pthread_getspecific (pthread_key_t key);
Notice that these two functions have a type of NULL pointer, and our thread is to use the two pointers to separate the
Data for thread-related data to interact with
(2)
Because P_key is a global variable,
function Another_func can access it without needing additional parameters;
And because it is "thread-related data", threads A, b data accessed through P_key are independent of each other,
This does not require additional mutex mechanisms to ensure data access is correct.