I. mutex lock
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 );
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.
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.
Lock function:
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.
Unlock function:
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 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.
Ii. Condition Variables
A condition variable is a mechanism for synchronizing global variables shared by threads. It mainly includes two actions: one thread waits for the condition variable to be established and suspends; another thread sets "condition to true" (a signal indicating condition to true ). To prevent competition, the use of condition variables is always combined with a mutex lock.
1. Create and log out
Like mutex lock, conditional variables have two static and dynamic creation methods. The static method uses the pthread_cond_initializer constant, as shown below:
Pthread_cond_t cond = pthread_cond_initializer
Call the pthread_cond_init () function dynamically. The API is defined as follows:
Int pthread_cond_init (pthread_cond_t * cond, pthread_condattr_t * cond_attr)
Although the POSIX standard defines attributes for condition variables, they are not implemented in linuxthreads. Therefore, the cond_attr value is usually null and ignored.
To cancel a condition variable, you must call pthread_cond_destroy (). This condition variable can be canceled only when no thread is waiting for the condition variable. Otherwise, ebusy is returned. Because the condition variables implemented in Linux do not allocate any resources, the logout action only includes checking whether there are waiting threads. The API is defined as follows:
Int pthread_cond_destroy (pthread_cond_t * Cond)
2. Waiting
Int pthread_cond_wait (pthread_cond_t * cond, pthread_mutex_t * mutex)
Int pthread_cond_timedwait (pthread_cond_t * cond, pthread_mutex_t * mutex, const struct timespec * abstime)
There are two waiting conditions: pthread_cond_wait () and pthread_cond_timedwait (). If the waiting time is not met before the given time, etimeout is returned and the waiting time ends, here, abstime appears in the absolute time format of the same meaning as the time () system call. 0 indicates GMT 00:00:00, January 1, January 1, 1970.
Pthread_cond_wait will first remove the previously pthread_mutex_lock-locked content, and then block the Waiting waiting for sleep in the column until it is awakened again (in most cases, the waiting conditions are met and then awakened, this process will first lock the first pthread_mutex_lock (& CTX); and then read the resource.
Either way, you must work with a mutex lock to prevent multiple threads from simultaneously requesting the Race Condition of pthread_cond_wait () (or pthread_cond_timedwait (), the same below ). Mutex locks must be common locks (pthread_mutex_timed_np) or adaptive locks (pthread_mutex_adaptive_np), and must be locked by this thread before pthread_cond_wait () is called ()), before the update condition is waiting for the queue, mutex remains locked and is unlocked before the thread is suspended and enters the waiting state. Before the condition is met and pthread_cond_wait () is left, mutex is re-locked to match the lock action before pthread_cond_wait.
3. Excitation
There are two ways to activate the condition. pthread_cond_signal () activates a thread waiting for the condition. When there are multiple waiting threads, one of them is activated in the queue order; and pthread_cond_broadcast () activate all the waiting threads.
Pthread_cond_wait () will execute the last operation: Re-lock mymutex. Once pthread_cond_wait () locks the mutex object, it will return and allow thread 1 to continue execution. At that time, it can immediately check the list and view the changes it is interested in.
Let's review it first. The first thread first calls:
Pthread_mutex_lock (& mymutex );
Then, it checks the list. Something of interest is not found, so it calls:
Pthread_cond_wait (& mycond, & mymutex );
Then, the pthread_cond_wait () call performs many operations before the return:
Pthread_mutex_unlock (& mymutex );
It unlocks mymutex and then enters sleep state, waiting for mycond to receive the POSIX thread "signal ". Once a "signal" is received (quotes are enclosed because we are not discussing traditional UNIX signals, but the signals from pthread_cond_signal () or pthread_cond_broadcast () calls), it will wake up. But pthread_cond_wait () does not return immediately -- it also needs to do one thing: Re-lock mutex:
Pthread_mutex_lock (& mymutex );
Pthread_cond_wait () knows the changes behind mymutex, so it continues to lock the mutex for us before returning.