In the previous two articles, we introduced two types of thread synchronization objects: mutex and read/write lock in Linux. These two types of thread synchronization objects are used to protect specific resources (memory, file handle, etc. If a thread needs to wait for the system to be in a certain state to continue execution, Linux introduces a thread synchronization object such as a condition variable to solve this problem. This article briefly introduces the condition variable.
The condition variable must be used together with the mutex, allowing the thread to wait for the occurrence of a specific condition in a non-competitive manner. The thread must lock the mutex of the Protection Condition variable before waiting for the condition variable and the notification condition variable.
Like other thread synchronization objects, conditional variables need to be initialized and destroyed. The function is defined as follows:
#include <pthread.h> int pthread_cond_destroy(pthread_cond_t *cond); int pthread_cond_init(pthread_cond_t *restrict cond, const pthread_condattr_t *restrict attr); pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
Conditional variables can be initialized using the pthread_cond_initializer constant or the pthread_cond_init function. Destroy the call pthread_cond_destroy.
The Function Definition of the thread wait condition variable is as follows:
#include <pthread.h> int pthread_cond_timedwait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex, const struct timespec *restrict abstime); int pthread_cond_wait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex);
The difference between the two functions is that the former specifies a timeout time, blocks the call thread within the time, and waits for the condition variable. If the condition has not occurred within the specified time, the function returns, the error value etimedout is returned, and the latter will always block the call thread until the condition occurs.
Note that before using these two functions, you must first lock the mutex that protects the conditional variables, then, the mutex of the lock is used as the parameter call condition to change.
Wait function. Wait for the function to unlock the mutex internally. Why should we unlock the mutex? When a condition occurs, the action of the notification condition variable is protected by the mutex.
The mutex is not released, so the conditions it waits for will never happen and will enter the deadlock status. Now let's talk about the conditional variable notification function.
The waiting call of typical condition variables is as follows: 1) Lock the mutex. 2) use this mutex as a parameter to call the function that waits for the conditional variable. 3) process the condition after the condition occurs. 4) unlock the mutex.
When a condition variable has been met, you can call the following function to activate the waiting thread.
#include <pthread.h> int pthread_cond_broadcast(pthread_cond_t *cond); int pthread_cond_signal(pthread_cond_t *cond);
Pthread_cond_signal will activate one of the waiting threads; pthread_cond_broadcast will activate all threads. In addition, note that these two functions also require mutex protection.
The typical method for activating conditional variables is as follows: 1) Lock the mutex. 2) modify the conditions and do what you should do. 3) release mutex. 4) Call the above two functions to notify the waiting thread.
Pay attention to Steps 3 and 4 in the above four steps. Do not reverse it. Otherwise, an error will occur and the function may not be executed. (The consequences are unknown due to thread competition ). Analyze the specific causes on your own.
Original