Thread-Private data (thread-specific DATA,TSD): a mechanism for storing and querying data related to a thread.
All threads within a process share the same address space, meaning that any variables declared as static or external variables, or declared in the process heap, can be read and written by all threads in the process.
The only private storage that a thread really owns is a processor register, which is also shared when "master" is deliberately exposed to other threads.
Sometimes it is necessary to provide thread-private data: It can be accessed across multiple functions (global), and only one thread is valid (private) (that is, it is global within the thread). For example: errno.
All threads in a process can access the entire address space of the process, except that the thread has no way to prevent other threads from accessing its data, unless it is using a register (the only private storage that a thread really owns is a processor register), and thread-private data is no exception. But functions that manage thread-private data can improve data independence between threads.
All threads in the process share the data space of the process, so global variables are common to all threads. But sometimes threads also need to save their own private data, and you can create thread-private data (thread-specific Date) TSD to resolve them. Inside a thread, private data can be accessed by individual functions, but it is blocked for other threads. For example, our common variable errno, which returns the standard error message. It obviously cannot be a local variable, and almost every function should be able to call it, but it cannot be a global variable. (that is, the thread inside is a global variable)
Creating thread-private data is so that the internal functions of the thread can easily pass the data information, so the function outside the thread cannot access the data, and the function within the thread uses the data like a global variable within a thread, which is global within a thread. Typically, the address of a thread's private data is used as a portal for accessing the data within a thread.
Thread-Private data employs a technique called one-key multivalued, that is, a key that corresponds to multiple values. Access to data is accessed through key values, as if accessing a variable is actually accessing different data. When using thread-private data, you first create an associated key for each thread's private data. Within each thread, this common key is used to refer to the thread data, but in different threads, the key represents a different data. There are 4 functions that manipulate thread private data: pthread_key_create (Create a key), pthread_setspecific (set thread-private data for a key), pthread_getspecific (read thread-private data from a key) , Pthread_key_delete (Deletes a key).
Create a key:
[CPP] View Plaincopyprint
01.int pthread_key_create (pthread_key_t *keyp, Void (*destructor) (void *))//return value: Return 0 if successful, otherwise return error number
int Pthread_key_create (pthread_key_t *keyp, Void (*destructor) (void *))//Return value: Returns 0 if successful, otherwise the error number is returned before allocating (malloc) thread private data. You need to create a key that is associated with the thread's private data, which is the ability to gain access to the thread's private data.
If you create a thread private Data key, you must ensure that pthread_key_create is only called once for each pthread_key_t variable, because if a key is created two times, it is actually creating two different keys, the second key will overwrite the first key, The first key and the thread private data values that any thread might associate with it will be lost.
When you create a new key, the private data address for each thread is set to NULL.
Note: The key that is created is stored in the memory unit that the KEYP points to, which can be used by all threads in the process, but each thread associates the key with a different thread private data address.
In addition to creating keys, Pthread_key_create can optionally associate destructors for the key, and when the thread exits, the destructor is invoked if the thread private data address is set to a Non-null value.
Note: The destructor argument is the address of the private data for the exit thread. If the address of the private data is null, it means that there is no destructor associated with the key-that is, no need to invoke the destructor.
Destructors are invoked when the thread calls Pthread_exit or when the thread executes, but the destructor is invoked if the thread calls the exit, _exit, Exit function, or abort or some other abnormal exit.
Threads typically use malloc to allocate space for thread-private data, and destructors typically release memory of allocated thread-private data.
Threads can assign multiple keys to thread-private data, and each key can have a destructor associated with it. The destructors for each key can be different, but they can also use the same destructor.
When a thread exits, the destructor of the thread's private data is invoked in the order defined by the operating system implementation. A destructor might call another function, which might create new thread-private data and associate the thread's private data with the current key. When all destructors are called, the system checks to see if there is a non-null thread private data value associated with the key, and if so, calls the destructor again, which repeats to the thread that all keys are null-value thread-private data, or have been pthread_destructor The maximum number of attempts defined in the _iterations.
To cancel the association between a key and a thread's private data:
[CPP] View Plaincopyprint
01.int Pthread_delete (pthread_key_t *keyp)//return value: Return 0 if successful, otherwise return error number
int Pthread_delete (pthread_key_t *keyp)//return value: Returns 0 if successful, otherwise returns error number note the call Pthread_delete does not activate the destructor associated with the key. When you delete a thread private data key, it does not affect the thread-private data values that are set on the key by any thread, or even the current key value of the calling thread, so it is easy to cause a memory leak (because the key is not associated with private data, and the key destructor is not invoked when the thread This memory is not released because the thread's private data is eventually created. Using private data keys that have been removed will result in undefined behavior.
Note: You must call pthread_key_create only once for each pthread_key_t variable (that is, the key). If a key is created two times, it is actually creating a different key, the second key will overwrite the first one, and the value that the first key and any thread may set will be lost forever. Therefore, Pthread_key_create is executed in the main function, or each thread uses Pthread_once to create the key.