条件锁就是所谓的条件变量,某一个线程因为某个条件为满足时可以使用条件变量使改程序处于阻塞状态。条件锁强调的是条件等待而不是互斥,条件锁会阻塞当前线程,直到某个条件成立才会继续向下执行。
条件变量是线程可用的另一种同步机制。互斥量用于上锁,条件变量则用于等待,并且条件变量总是需要与互斥量一起使用,运行线程以无竞争的方式等待特定的条件发生。
条件变量本身是由互斥量保护的,线程在改变条件变量之前必须首先锁住互斥量。其他线程在获得互斥量之前不会察觉到这种变化,因为互斥量必须在锁定之后才能计算条件。如果条件不满足,则解锁互斥量,并将该线程置于阻塞或等待状态。当条件满足会有信号通知该线程,使其从阻塞态变为就绪态。当重新获取互斥量上的锁,并再次检查条件,如果条件已经满足,就继续往下执行,否则又会解锁互斥量,使线程重新放回到阻塞状态。
int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr);//初始化条件变量
int pthread_cond_destroy(pthread_cond_t *cond);//销毁条件变量
int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex);//无条件等待条件变量变为真
int pthread_cond_timewait(pthread_cond_t *cond, pthread_mutex_t *mutex, const struct timespec *tsptr);//在给定时间内,等待条件变量变为真
#include <list>
#include <mutex>
#include <condition_variable>
//使用std::condition_variable等待数据
std::mutex mut;
std::queue<int> data_queue;
std::condition_variable data_cond;
void data_preparation_thread()
{
while(true)
{
int const data = prepare_data();
std::lock_guard<std::mutex> myMux(mut);
data_queue.push(data);
data_cond.notify_one();
}
}
void data_processing_thread()
{
while(true)
{
std::unique_lock<std::mutex> myMux(mut);
// 如果条件不满足,wait()解锁互斥元,并将该线程置于阻塞或等待状态;
// 当来自数据准备线程中对notify_one()的调用通知条件变量时,线程从睡眠状态中苏醒(解除其阻塞)变为就绪态,
// 重新获得互斥元上的锁,并再次检查条件,如果条件已经满足,就从wait()返回值,互斥元仍被锁定。
// 如果条件不满足,该线程解锁互斥元,并恢复阻塞等待。
data_cond.wait(myMux, {[]return !data_queue.empty();});
int data = data_queue.front();
data_queue.pop();
myMux.unlock();
process(data);
}
}