生产者消费者模型中条件变量的使用

目录

        • 生产者消费者模型简介
        • 条件变量cond
        • pthread_cond_wait

生产者消费者模型简介

生产者消费者模型中有两种角色, 一种是生产者, 一种是消费者.(这不是废话么)这个模型一般是配合多线程环境使用的

生产者线程负责生产资源, 消费者线程负责使用(消费)资源. 由于资源是双方共享的临界资源, 那么在多线程的环境下就必然会涉及到线程安全的问题, 因此模型必须满足如下的要求:

  1. 临界资源每次只能被一个线程访问.
  2. 资源满时生产者停止生产; 资源空时消费者不得消费.

为实现如上要求常需要使用条件变量(cond)和锁(mutex):

条件变量cond

Linux下使用条件变量需要包含一个头文件, 由于生产者和消费者是两种角色, 我们需要使用两个条件变量来分别管理这些线程.
比如说

pthread_cond_t producer_cond;
pthread_cond_t consumer_cond;

条件变量在使用前需要使用pthread_cond_init函数初始化

pthread_cond_wait

函数原型
int pthread_cond_wait(pthread_cond_t * cond, pthread_mutex_t * mutex);
函数本身是不需要锁的, 参数列表中的mutex是函数的设计者为了方便用户的使用而添加的
调用了pthread_cond_wait函数的线程, 首先会释放锁资源, 然后被放入PCB等待队列中挂起, 直到被别的进程唤醒(或者时间到了), 唤醒之后会去竞争锁资源. 也就是说, pthread_cond_wait函数封装了释放锁资源、挂起等待、获取锁资源这三步
在生产者消费者模型当中, 资源满时生产者调用pthread_cond_wait, 资源空时消费者调用pthread_cond_wait, 那么代码逻辑要怎么写呢?
比如说生产者

if(Full()){
	pthread_cond_wait(&producer_cond, &lock);
}

我们来看看这样写有什么问题.假设 线程A 线程B 都是生产者线程, 某一时刻两线程被同时唤醒, 于是两者开始争夺锁资源, 假设线程B抢到了锁, 线程A就卡在了pthread_mutex_lock(&lock)函数中, 然后当线程B生产完释放锁后, 线程A抢到了锁, 并开始生产资源, 然而此时由于线程B已经生产了一个资源, 资源已经满了, 线程A实际上不应该生产资源, 而是继续等待.
因此代码应该这样改:

while(Full()){
	pthread_cond_wait(&producer_cond, &lock);
}

这样, 每个生产者线程在每次抢到锁之后都要去判断临界资源是否已满, 从而保证了资源访问的合理性

你可能感兴趣的:(C++学习)