条件变量
pthread_cond_t
pthread_cond_init()
pthread_cond_destroy()
pthread_cond_wait()
pthread_cond_signal()
pthread_cond_broadcast()
条件变量的作用:可以使某个在判断当前条件为满足时,阻塞在条件变量上,当条件满足时其他线程可以唤醒阻塞在条件变量上的线程
pthread_cond_wait()
功能:1 阻塞 2 解除已经获取的锁(1 2 这两个行为是一个原子操作,不可分割)
当某个线程通过pthread_cond_signal或pthread_cond_broadcast唤醒阻塞在当前条件变量上的线程时
3 解除阻塞 4 重新申请锁
pthread_cond_signal(): 唤醒一个阻塞在条件变量上的线程
pthread_cond_broadcast(): 唤醒全部阻塞在条件变量上的线程
一生产者一消费者模型
生产者消费者模型框架:
使用条件变量+链表实现的生产者消费者模型
生产者
while(1){
产生数据,得到一个需要放到缓冲区交给消费者处理的数据
先加锁
将得到的数据放入到链表中
通知消费者 消费者期待的条件已经满足
解锁
}
消费者
while(1){
加锁
判断我们期待的条件是否满足(链表不能为空)
如果期待的事件不满足
阻塞在条件变量上(线程阻塞,并释放锁)
如果期待的事件满足
先从链表上摘下一个任务节点
解锁
处理数据
}
正确使用条件变量的生产者消费者模型(多线程生产者多线程消费者)
这里提到的多线程生产者多线程消费者为什么和上面的一生产一消费不同呢?其实在本质上没有太大区别,只是把消费者里的if判断改成了whie判断,因为在多个线程同步进行时候,多个消费者可能会集体阻塞在if判断里的wait函数上,但是当被生产者的唤醒函数唤醒时只有一个线程能抢到锁并加锁然后执行后续操作,其他线程均还阻塞在wait 上,当抢到锁的线程执行完后解锁,下一个线程才会被唤醒并抢到锁,此时并不确定的是上一个线程在数据上留下了什么样的结果,比如又把节点删空的情况,这时刚抢到锁的线程继续运行就会出错,所以换成while后每次抢到锁的线程都会重复判断是否拥有能满足后续代码运行的条件,这样就不会出错。