- 使用场景
条件变量+互斥锁用于“生产-消费模型”,如下图所示:
当仓库没有位置的时候,就要要求所有的生产者不可以再生产了。
当仓库空的了时候,就要要求所有的消费者不可以再消费了。
当仓库又有位置的时候,就要通知生产者可以继续生产了。
当仓库非空的时候,就要通知消费者可以继续消费。
- 使用方法及函数
条件变量引用头文件pthread.h
条件变量定义:pthread_cond_t cond;
涉及的函数:
pthread_mutex_init();初始化函数
pthread_mutex_destory; 销毁函数
pthread_wait()函数,实参为条件变量,互斥锁
pthread_timewait()函数
pthread_signal()函数:通知对方醒一个线程
pthread_broadcast()函数:通知对方所有线程都醒。
- 使用实例:
主函数中初始化了互斥锁和条件变量。同时创建了五个生产者线程,5个消费者线程。
但是下面程序需要再加上pthread_join回收资源。
消费者线程回调函数:
在此函数中,如果所有的仓位都空了,消费者就不能进行消费了,因此需要判断if(headnull),如果为空,则需要阻塞消费者线程。阻塞的方法即pthread_cond_wait(&cond,&mutex)
那么,如果所有的线程都阻塞在这里了,由谁来唤醒呢?当然是生产者回调函数了。
如下:
4. 问题
(1) 为何要加条件变量
在消费者模型中,直接判断if(headnull)再执行不就可以了吗?为何还要增加条件变量阻塞?
这个原因是if(head ==null)直接写程序的话,会导致互斥锁不停的被线程加锁解锁,加锁解锁,浪费了很多模型效率。
(2) 为何pthread_cond_wait()函数中的形参要有mutex锁?
这要从pthread_cond_wait()函数本身内部的功能说起。
此函数内部需要先解锁mutex,再等待,离开此函数前再加锁?
因此在pthread_cond_wait()之前需要先加互斥锁,然后再调用pthread_cond_wait函数。
为何?提前加锁的原因是为了防止在进入wait之前条件改变。
具体可以参考:
https://blog.csdn.net/shichao1470/article/details/89856443