Linux multi-thread synchronization-mutex-general Linux technology-Linux programming and kernel information. The following is a detailed description. 1. Initialization:
In Linux, the thread mutex data type is pthread_mutex_t. Before use, initialize it:
For the mutex of static allocation, you can set it to PTHREAD_MUTEX_INITIALIZER or call pthread_mutex_init.
For the dynamically allocated mutex, after applying for memory (malloc), initialize with pthread_mutex_init and call pthread_mutex_destroy before releasing the memory (free.
Prototype:
Int pthread_mutex_init (pthread_mutex_t * restrict mutex, const pthread_mutexattr_t * restric attr );
Int pthread_mutex_destroy (pthread_mutex_t * mutex );
Header file:
Return Value: 0 is returned for success, and error number is returned for error.
Note: If you use the default attribute to initialize mutex, you only need to set attr to NULL. Other values will be explained later.
2. mutex operation:
To access shared resources, You need to lock the mutex. If the mutex has been locked, the calling thread will be blocked until the mutex is unlocked. after accessing the shared resources, unlock the mutex.
First, let's talk about the locking function:
Header file:
Prototype:
Int pthread_mutex_lock (pthread_mutex_t * mutex );
Int pthread_mutex_trylock (pthread_mutex_t * mutex );
Return Value: 0 is returned for success, and error number is returned for error.
Description: The trylock function is a non-blocking call mode. That is, if the mutex is not locked, the trylock function locks the mutex, and obtain the access permission for the shared resources. If the mutex is locked, the trylock function will not block the wait and return EBUSY directly, indicating that the shared resources are busy.
Let's talk about the function:
Header file:
Prototype: int pthread_mutex_unlock (pthread_mutex_t * mutex );
Return Value: 0 is returned for success, and error number is returned for error.
3. deadlock:
A deadlock occurs when multiple dependency locks exist, and occurs when a thread tries to lock the mutex in the reverse order of the other thread. It is important to avoid a deadlock when mutex is used.
In general, there are several unwritten basic principles:
You must obtain the lock before operating on shared resources.
The lock must be released after the operation is completed.
Use the lock as soon as possible.
If there are multiple locks, for example, if the order is ABC, the release order should also be ABC.
When a thread returns an error, it should release the lock it obtained.
After talking about this, let me give an example of the actual point to illustrate the functions of the above functions:
(Code Source: GPRS Server Linux programming Author: Li Yangming)
CODE: # include # Include # Include # Include # Include Pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; Int lock_var; Time_t end_time; Int sum; Void pthread1 (void * arg ); Void pthread2 (void * arg ); Void pthread3 (void * arg ); Int main (int argc, char * argv []) { Pthread_t id1, id2, id3; Pthread_t mon_th_id; Int ret; Sum = 10; End_time = time (NULL) + 10; Pthread_mutex_init (& mutex, NULL ); Ret = pthread_create (& id1, NULL, (void *) pthread1, NULL ); If (ret! = 0) Perror ("pthread cread1 "); Ret = pthread_create (& id2, NULL, (void *) pthread2, NULL ); If (ret! = 0) Perror ("pthread cread2 "); Ret = pthread_create (& id3, NULL, (void *) pthread3, NULL ); If (ret! = 0) Perror ("pthread cread3 "); Pthread_join (id1, NULL ); Pthread_join (id2, NULL ); Pthread_join (id3, NULL ); Exit (0 ); } Void pthread1 (void * arg) { Int I; While (time (NULL) <end_time) { If (pthread_mutex_lock (& mutex )! = 0) // lock { Perror ("pthread_mutex_lock "); } Else Printf ("pthread1: pthread1 lock the variable \ n "); For (I = 0; I <2; I ++) { Sleep (2 ); Lock_var ++; } If (pthread_mutex_unlock (& mutex )! = 0) // unlock { Perror ("pthread_mutex_unlock "); } Else Printf ("pthread1: pthread1 unlock the variable \ n "); Sleep (1 ); } } Void pthread2 (void * arg) { Int nolock = 0; Int ret; While (time (NULL) <end_time) { Ret = pthread_mutex_trylock (& mutex); // try lock If (ret = EBUSY) Printf ("pthread2: the variable is locked by pthread1 \ n "); Else { If (ret! = 0) { Perror ("pthread_mutex_trylock "); Exit (1 ); } Else Printf ("pthread2: pthread2 got lock. The variable is % d \ n", lock_var ); If (pthread_mutex_unlock (& mutex )! = 0) // unlock { Perror ("pthread_mutex_unlock "); } Else Printf ("pthread2: pthread2 unlock the variable \ n "); } Sleep (1 ); } } Void pthread3 (void * arg) {/* Int nolock = 0; Int ret; While (time (NULL) <end_time) { Ret = pthread_mutex_trylock (& mutex ); If (ret = EBUSY) Printf ("pthread3: the variable is locked by pthread1 or 2 \ n "); Else { If (ret! = 0) { Perror ("pthread_mutex_trylock "); Exit (1 ); } Else Printf ("pthread3: pthread3 got lock. The variable is % d \ n", lock_var ); If (pthread_mutex_unlock (& mutex )! = 0) { Perror ("pthread_mutex_unlock "); } Else Printf ("pthread3: pthread2 unlock the variable \ n "); } Sleep (3 ); }*/ } |