对于只有一个锁的情况,死锁发生在消费者获取锁之后一直不释放。如果每次生产者先于消费者拿到锁,譬如先启动生产者,然后等待一段时间后再去启动消费者,这个死锁是可以避免的。但是真实的情况,生产者和消费者的启动时机是内核负责调度的,谁先谁后系统没有保证。所以要考虑消费者先于生产者运行的情形该怎么避免死锁。
而解决死锁的本质在于,要给生产者线程进入临界区域的时机(一般来说,消费者死锁很容易避免)。解决方式有两种:
一种是,消费者检查到资源没有准备好之后,unlock,等待一段时间,再次获取锁,重新检查资源是否准备好;如果资源准备好了,就直接unlock返回了。资源没有准备好的模式是: unlock, wait(time),lock。
另一种是在方法一基础上做了改进,就是消费者检查到资源没有准备好,unlock之后,用Condition variable 进行等待。方法一等待的时间是用户指定的。而这里等待的时间,取决于生产者什么时候唤醒这个Condition variable。Condition variable被唤醒后,会再次去lock,然后检查资源是否准备好。资源没有准备好的模式是::unlock, wait(signal),lock。
死锁问题
死锁发生在消费者先获得锁,然后不停的检查条件是否为真。与此同时,生产者会被调度出去,也没有机会把消费者等待的条件修改为真。所以,这个时候,消费者一直在检查条件是否为真,生产者一直处于睡眠状态。两者形成死锁。
void ThreadConsumer() {
unique_lock