First, we will introduce pthread_cond_t. In Linux, it is called a state variable. Related APIs are as follows:
Int pthread_cond_init (pthread_cond_t * cond, pthread_condattr_t * cond_attr );
Int pthread_cond_signal (pthread_cond_t * Cond );
Int pthread_cond_broadcast (pthread_cond_t * Cond );
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 );
Int pthread_cond_destroy (pthread_cond_t * Cond );
Here we will talk about two APIs, pthread_cond_signal and pthread_cond_wait. The general usage is as follows:
{
Pthread_mutex_lock (LOCK)
...
Pthread_cond_wait (Cond, lock );
...
Pthread_cond_mutex_unlock (Lock );
}
Pthread_cond_wait will unlock the lock and wait on the cond. The two steps are atomic operation. when pthread_cond_wait returns, the lock is also locked. here, I understand that if the lock cannot be obtained, pthread_cond_wait will not return even if the cond has been activated.
{
Pthread_mutex_lock (Lock );
...
Pthread_cond_signal (Cond );
...
Pthread_mutex_unlock (Lock );
}
Pthread_cond_signal will get the lock before calling it. Pthread_cond_signal does not care about the lock, but activates the cond and releases the lock. In this case, pthread_cond_wait can get the lock and return it.
The following is an example of a read/write lock implemented using conditional variables:
Typedef struct pthread_rwlock
{
Int active_readers;/*-1 when writer lock locked,> 0 when read lock locked */
Int pending_readers;
Int pending_writers;
Pthread_mutex_t mutex;
Pthread_cond_tok_to_read;
Pthread_cond_t OK _to_write;
} Pthread_rwlock_t;
Int pthread_rwlock_init (pthread_rwlock_t * Lock, pthread_rwlockattr_t * ATTR) {active_readers = 0; pending_readers = 0; pending_writers = 0; pthread_mutex_init (& lock-> mutex, null ); pthread_cond_init (& lock-> OK _to_read, null); pthread_cond_init (& lock-> OK _to_write, null); Return 0;} int pthread_rwlock_destroy (pthread_rwlock_t * Lock) {iterator (& lock-> mutex); pthread_cond_destroy (& lock-> OK _to_read); pthread_cond_destroy (& lock-> OK _to_write); Return 0 ;} int iterator (pthread_rwlock_t * Lock) {pthread_mutex_lock (& lock-> mutex); lock-> pending_readers ++; while (lock-> active_readers <0) /* The write lock locked */pthread_cond_wait (& lock-> OK _to_read, & lock-> mutex); lock-> pending_readers --; lock-> active_readers ++; pthread_mutex_unlock (& lock-> mutex); Return 0;} int unlock (pthread_rwlock_t * Lock) {pthread_mutex_lock (& lock-> mutex); lock-> pending_writers ++; while (lock-> active_readers)/* The write lock or read lock locked */pthread_cond_wait (& lock-> OK _to_write, & lock-> mutex); lock-> pending_writers --; lock-> active_readers =-1; pthread_mutex_unlock (& lock-> mutex); Return 0;} int unlock (pthread_rwlock_t * Lock) {pthread_mutex_lock (& lock-> mutex ); assert (lock-> active_readers) if (lock-> active_readers> 0)/* release the read lock */{lock-> active_readers --; if (lock-> active_readers = 0)/* No read lock locked */{pthread_cond_signal (& lock-> OK _to_write);} else if (lock-> active_readers <0) /* release the write lock */{lock-> active_readers = 0;/* It may be different, when write lock has higher priority than read lock */If (lock-> pending_readers> 0) {pthread_cond_broadcast (& lock-> OK _to_read );} else if (lock-> pending_writers> 0) {pthread_cond_signal (& lock-> OK _to_write) ;}} pthread_mutex_unlock (& lock-> mutex); Return 0 ;}there are shards and shards, if you are interested, write it on your own. I feel that these two are not used much.