Linux programming-thread private data, linux programming thread private
In multi-threaded programs, global variables are often used to share data among multiple functions. Because the data space is shared, global variables are also shared by all threads.
The test code is as follows:
# Include <stdio. h> # include <pthread. h> # include <unistd. h> # include <stdlib. h> int key = 100; // global Variable void * helloworld_one (void * arg) {printf ("the message is % s \ n", (char *) arg ); key = 10; printf ("key = % d, the child id is % lu \ n", key, pthread_self (); return NULL ;} void * helloworld_two (void * arg) {printf ("the message is % s \ n", (char *) arg); sleep (1 ); printf ("key = % d, the child id is % lu \ n", key, pthread_self (); return NULL;} int main (int argc, char * argv []) {pthread_t thread_id_one; pthread_t success; // create thread pthread_create (& thread_id_one, NULL, helloworld_one, "helloworld_one"); pthread_create, "helloworld_two"); // wait for the end of the thread to recycle resources pthread_join (thread_id_one, NULL); pthread_join (thread_id_two, NULL); return 0 ;}
The running result is as follows:
The running results show that the modification of global variables by one thread affects the access of another thread.
However, sometimes it is necessary to provide a global variable private to the thread in the application design. This variable is valid only in the thread, but can be accessed across multiple functions. For example, each thread may need to maintain a linked list in the program, and the same function will be used to operate the linked list. The simplest way is to use the thread-related data structure with the same name and different variable addresses. Such a Data structure can be maintained by the Posix Thread library and become the Thread-specific Data (or TSD ).
The header files required for the following interface:
# Include <pthread. h>
1) Create thread private data
Int pthread_key_create (pthread_key_t * key, void (* destructor) (void *));
Function:
Create a private data variable (key) of the pthread_key_t type ).
Parameters:
Key: Before allocating (malloc) thread private data, you need to create a key associated with the thread private data. This key is used to obtain access to the thread private data.
Destructor: Clears the function name (for example, fun ). When the thread exits, this function is automatically called if the private data address of the thread is not NULL. This function pointer can be set to NULL, so that the system will call the default cleanup function.
The callback function is defined as follows:
Void fun (void * arg)
{
// Arg is the key value
}
Return Value:
Success: 0
Failed: Not 0
No matter which thread calls pthread_key_create (), the created key is accessible to all threads, but each thread can enter different values in the key as needed, it is equivalent to providing a variable with different values of the same name.
2) cancel the private data of the thread
Int pthread_key_delete (pthread_key_t key );
Function:
Cancels the private data of a thread. This function does not check whether the current thread is using the thread private data (key), nor call the cleaning function destructor (), but only sets the thread private data (key) release for the next call to pthread_key_create.
Parameters:
Key: Private data to be canceled.
Return Value:
Success: 0
Failed: Not 0
3) set the association of thread private data
Int pthread_setspecific (pthread_key_t key, const void * value );
Function:
Set the correlation between the private data (key) of the thread and the value. Note that the value (not the content) is associated with the key.
Parameters:
Key: Private data of the thread.
Value: Pointer associated with the key.
Return Value:
Success: 0
Failed: Not 0
4) read the value associated with the private data of the thread
Void * pthread_getspecific (pthread_key_t key );
Function:
The value associated with the read thread's private data (key.
Parameters:
Key: Private data of the thread.
Return Value:
Success: the value associated with the private data (key) of the thread.
Failed: NULL
The sample code is as follows:
// This is the test code for pthread_key # include <stdio. h> # include <pthread. h> pthread_key_t key; // Private Data, global Variable void echomsg (void * t) {printf ("[destructor] thread_id = % lu, param = % p \ n ", pthread_self (), t);} void * child1 (void * arg) {int I = 10; pthread_t tid = pthread_self (); // thread No. printf ("\ nset key value % d in thread % lu \ n", I, tid); pthread_setspecific (key, & I ); // set private data printf ("thread one sleep 2 until thread two finish \ n"); sleep (2); printf ("\ nthread % lu returns % d, add is % p \ n ", tid, * (int *) pthread_getspecific (key), pthread_getspecific (key);} void * child2 (void * arg) {int temp = 20; pthread_t tid = pthread_self (); // thread number printf ("\ nset key value % d in thread % lu \ n", temp, tid ); pthread_setspecpacific (key, & temp); // set the private data sleep (1); printf ("thread % lu returns % d, add is % p \ n", tid, * (int *) pthread_getspecific (key), pthread_getspecific (key);} int main (void) {pthread_t tid1, tid2; pthread_key_create (& key, echomsg ); // create pthread_create (& tid1, NULL, child1, NULL); pthread_create (& tid2, NULL, child2, NULL); pthread_join (tid1, NULL); pthread_join (tid2, NULL); pthread_key_delete (key); // cancel return 0 ;}
The running result is as follows:
According to the running results, each thread has no influence on its own private data operations. That is to say, although the key is the same name and global, the accessed memory space is not the same.
For sample code downloading in this tutorial, click here.
This article