A condition variable compensates for the lack of a mutex by allowing the thread to block and wait for another thread to send a signal, which is often used in conjunction with a mutex lock. When used, a condition variable is used to block a thread, and when the condition is not satisfied, the thread often unlocks the corresponding mutex and waits for the condition to change. Once another thread changes the condition variable, it notifies the corresponding condition variable to wake one or more threads that are being blocked by this condition variable. These threads will lock the mutex again and test the condition for satisfaction. In general, conditional variables are used to synchronize between lines.
1. The structure of the conditional variable is pthread_cond_t (equivalent to the role of events in Windows)
2. Initialization of conditional variables
int Pthread_cond_init __p (pthread_cond_t *__cond,__const pthread_condattr_t *__cond_attr));
Where cond is a pointer to the structure pthread_cond_t, cond_attr is a pointer to the structure pthread_condattr_t. Structure pthread_condattr_t is the property structure of the conditional variable, as is the mutex we can use it to set whether the condition variable is available within the process or between processes, the default value is Pthread_ process_private, That is, this condition variable is used by individual threads within the same process. Note Initialization criteria variables can be reinitialized or released only if they are not in use.
3. Release of conditional variables
The function to release a condition variable is pthread_cond_ destroy (pthread_cond_t cond)
4. Waiting for the conditional variable
(1) function pthread_cond_wait () causes the thread to block on a condition variable. Its function prototype is:
extern int pthread_cond_wait_p ((pthread_cond_t *__cond,pthread_mutex_t *__mutex));
The thread unlocks the lock that the mutex points to and is blocked by the condition variable cond. Threads can be awakened by function pthread_cond_signal and function pthread_cond_broadcast, but it is important to note that the condition variable only acts as a blocking and wake-up thread, and the specific judgment conditions need to be given by the user, such as whether a variable is 0, etc. This we can see from the example that follows. When a thread wakes up, it checks to see if the condition is satisfied, and if it is not, the thread should still be blocked here, waiting to be awakened next time. This process is generally implemented with a while statement.
(2) Another function to block a thread is pthread_cond_timedwait (), which is a prototype:
extern int pthread_cond_timedwait_p (pthread_cond_t *__cond,pthread_mutex_t *__mutex, __const struct Timespec *__ Abstime);
It is more than a function pthread_cond_wait () a time parameter, after experiencing abstime period of time, even if the condition variable is not satisfied, blocking is also lifted.
5. Change of condition variable
The prototype for the function pthread_cond_signal () is:
extern int pthread_cond_signal_p ((pthread_cond_t *__cond));
It is used to release a thread that is blocked on the cond of a condition variable. When multiple threads are blocking this condition variable, which thread is awakened is determined by the thread's scheduling policy. It is important to note that this function must be protected with a mutex that protects the condition variable, otherwise the condition satisfies the signal and may be emitted between the test condition and the call pthread_cond_wait function, resulting in unlimited waiting.
6. The following is a simple example of using the function pthread_cond_wait () and function pthread_cond_signal ().
pthread_mutex_t Count_lock;
pthread_cond_t Count_nonzero;
unsigned count;
Decrement_count () {
pthread_mutex_lock (&count_lock);
while (count==0)
pthread_cond_wait (&count_nonzero, &count_lock);
count=count-1;
Pthread_mutex_unlock (&count_lock);
}
Increment_count () {
pthread_mutex_lock (&count_lock);
if (count==0)
pthread_cond_signal (&count_nonzero);
count=count+1;
Pthread_mutex_unlock (&count_lock);
}