Thread data processing-thread data
To protect variables, we must use semaphores, mutex, and other methods to ensure correct use of variables.
1) thread data
In a single-threaded program, there are two basic types of data: global variables and local variables.However, in multi-threaded programs, there is also a third data type: thread data (TSD: thread-specific data ).It is similar to a global variable. In a thread, each function can call it like a global variable, but it is invisible to other threads outside the thread.
Usage of thread storage
Create a variable of the pthread_key_t type.
Call pthread_key_create () to create the variable. This function has two parameters. The first parameter is the above declared pthread_key_t variable, and the second parameter is a cleanup function, which is called when the thread releases the storage of this thread. This function pointer can be set to null, so that the system will call the default cleanup function.
When the thread needs to store special values, you can call pthread_setspcpacific (). This function has two parameters: the first is the previously declared pthread_key_t variable, and the second is the void * variable, so that you can store any type of value.
To retrieve the stored value, call pthread_getspecific (). The parameter of this function is the variable pthread_key_t mentioned earlier. This function returns a value of the void * type.
The following is a prototype of the previously mentioned function:
Int pthread_setspecific (pthread_key_t key, const void * value );
Void * pthread_getspecific (pthread_key_t key );
Int pthread_key_create (pthread_key_t * Key, void (* destructor) (void *));
The following is an example of how to use thread storage:
# Include <malloc. h>
# Include <pthread. h>
# Include <stdio. h>
/* The key used to associate a log file pointer with each thread .*/
Static pthread_key_t thread_log_key;
/* Write message to the log file for the current thread .*/
Void write_to_thread_log (const char * message)
{
File * thread_log = (File *) pthread_getspecific (thread_log_key );
Fprintf (thread_log, "% s \ n", message );
}
/* Close the log file pointer thread_log .*/
Void close_thread_log (void * thread_log)
{
Fclose (File *) thread_log );
}
Void * thread_function (void * ARGs)
{
Char thread_log_filename [20];
File * thread_log;
/* Generate the filename for this thread's log file .*/
Sprintf (thread_log_filename, "thread % d. Log", (INT) pthread_self ());
/* Open the log file .*/
Thread_log = fopen (thread_log_filename, "W ");
/* Store the file pointer in thread-specific data under thread_log_key .*/
Pthread_setspecific (thread_log_key, thread_log );
Write_to_thread_log ("thread starting .");
/* Do work here ...*/
Return NULL;
}
Int main ()
{
Int I;
Pthread_t threads [5];
/* Create a key to associate thread Log File pointers in
Thread-specific data. Use close_thread_log to clean up the file pointers .*/
Pthread_key_create (& thread_log_key, close_thread_log );
/* Create threads to do the work .*/
For (I = 0; I <5; ++ I)
{
Pthread_create (& (threads [I]), null, thread_function, null );
}
/* Wait For All threads to finish .*/
For (I = 0; I <5; ++ I)
{
Pthread_join (threads [I], null );
}
Return 0;
}