条件变量基础

通常,条件变量和互斥锁搭配使用。

条件变量是用来弥补互斥锁的不足的。在我们使用互斥锁的时候,往往是为了等待某个线程修改完数据之类的条件满足后,释放互斥锁。这个过程中,其他线程会尝试竞争锁,竞争失败后才会进入阻塞队列,这个过程还是会消耗CPU的资源。

而使用条件变量以后,当条件满足的时候,会发送信号去唤醒等待这个条件的线程,去加锁,再判断条件是否满足

至于为什么要再判断条件,这个一会再提。

总之,使用条件变量以后,线程就不需要主动去竞争锁,而是等待着被唤醒,这样可以提高CPU是利用率。

1.初始化条件变量

与互斥锁一样,有静态和动态。

1.1静态初始化

pthread_cond_t cond = PTHREAD_COND_INITIALIZER;

1.2动态初始化

int pthread_cond_init(pthread_cond_t *cond, pthread_cond_addr_t *cond_attr);

参数分别是传入条件变量的地址,以及条件变量属性的结构体,如果默认属性填NULL即可。

2.条件变量的等待

2.1阻塞等待

int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex);

2.2超时等待

int pthread_cond_timewait(pthread_cond_t *cond, pthread_mutex_t *mutex, const timespec *abstime);

等待的过程有三步:(1)释放互斥锁;(2)等待被唤醒;(3)被唤醒,锁上互斥锁。这三步是分开的,并非原子操作

3.条件变量唤醒

3.1唤醒一个等待该条件的线程

int pthread_cond_signal(pthread_cond_t *cond);

3.2唤醒所有等待该条件的线程

int pthread_cond_broadcast(pthread_cond_t *cond);

4.销毁条件变量

int pthread_cond_destroy(pthread_cond_t *cond);

4.虚假唤醒

例如我们有一个生产者消费者程序,消费者从一个队列里面取数据,我们在等待条件变量的时候应该这么写。

pthread_mutex_lock(&mutex);
while(qu.empty()){
	pthread_cond_wait(&cond, &mutex);
}
/*
取数据操作
*/
pthread_mutex_unlock(&mutex);

其中,为什么要用一个while循环呢?

这就是有关虚假唤醒的问题。

当你同时唤醒多个线程的时候,有多个线程,其中一部分线程已经把队列里面的数据都取完了,而剩下的线程虽然也被唤醒了,但是队列已经空了,所以这是虚假唤醒。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值