Linux多线程编程(三)-----生产者与消费者(条件变量,信号量)

Linux多线程编程(一):http://blog.csdn.net/llzk_/article/details/55670172
Linux多线程编程(二):http://blog.csdn.net/llzk_/article/details/55805851
在前两篇文章中我们探讨了线程的概念,同步与互斥概念以及互斥锁。本文将剖析一种操作系统中重要的模型—–生产者与消费者。其中会涉及条件变量,互斥锁,信号量等概念。

概念

我认为,生产者消费者模型主要是用来解决资源的供求问题。生产者是资源的提供方,消费者是资源的需求方。此为两种角色

  • 生产者与消费者之间是供求关系
  • 两个生产者之间是竞争关系(互斥)
  • 两个消费者之间也是竞争关系(互斥)

此为三种关系
生产者与消费者进行交易,那必然需要一个交易场所。在现实生活中可以是饭店,商场等等。此为一个场所
记住这“3 2 1”规则,会为你理解这个模型提供很大的帮助。

下面我们举一个例子来进一步理解一下生产者与消费者间的关系。假定现在有一个商场。生产厂商为这个商场提供,我们去商场买商品。所以生产厂商是生产者,我们是消费者,商场是交易场所,商品就是连接关系的资源。

  • 当生产厂商为商场供货时,因为一些黑幕交易,我们此时是不能进商场消费的。
  • 当我们在商场消费时,厂商因为没有“安全”的环境,是不来供货的。

生产者(厂商)与消费者(我们)之间是互斥关系。不能同时访问交易场所。
但是也需要一种规则,来协同厂商与我们访问商场的时间。所以生产者(厂商)与消费者(我们)之间也是同步关系。(同步指协同)

条件变量

在理解了上面的同步与互斥之后,我们还要解决一个问题。假如你大老远跑来商场买东西,发现货架是空的,生产者并没有提供任何商品给你买。那你会不会很失望?
为了避免这种事情的发生,我们就需要条件变量来帮助我们。当有商品时,会通知你“有辣条了,快来买吧!”。当没有商品时,就一直等待。

定义

条件变量是利用线程间共享的全局变量进行同步的一种机制,主要包括两个动作:一个线程等待“条件变量的条件成立”;另一个线程使“条件成立”(给出条件成信号)。所以条件变量使我们可以睡眠等待某种条件出现。
为了防止竞争,条件变量的使用总是和一个互斥锁进行搭配。

函数接口

以下所有函数接口的头文件都是

#include
  • 条件变量的数据类型
pthread_cond_t
  • 条件变量初始化

条件变量初始化有两种方法:

①直接定义一个全局的条件变量,并利用宏PTHREAD_COND_INITIALIZER进行值得初始化。

pthread_cond_t cond = PTHREAD_COND_INITIALIZER;

②调用函数pthread_cond_init

pthread_cond_t (pthread_cond_t *restrict cond,
              const pthread_condattr_t *restrict attr);

第一个参数即为我们动态分配的条件变量cond,除非创建一个非默认属性的条件变量,否则第二个参数attr始终为NULL;
注意:若不想讲条件变量定义成全局的,必须以动态分配的方式创建。

pthread_cond_t *cond = (pthread_cond_t*)malloc(sizeof(pthread_cond_t));

注意:使用此种方式,先destroy(看下文)条件变量,再free这块空间。

  • 销毁条件变量

我们有创建条件变量,那必须得有销毁。调用pthread_cond_destroy函数销毁条件变量。

int pthread_cond_destroy(pthread_cond_t* cond);

参数cond指针即指向我们创建的条件变量。

  • 等待

我们使用pthread_cond_wait或pthread_cond_timewait函数等待条件变量变为真。

int pthread_cond_timedwait(pthread_cond_t *restrict cond,pthread_mutex_t *restrict mutex,const struct timespec *restrict abstime);
int pthread_cond_wait(pthread_cond_t *restrict cond,pthread_mutex_t *restrict mutex);

我们先说pthread _cond_wait,其第一个参数是指向条件变量的指针,第二个参数是一个指向互斥锁的指针。在上面提到过,条件变量总是和一把互斥锁协同使用的。目的是为了防止资源的竞争。这里的资源暂且理解为商场。(关于互斥锁不懂的可参照文章开头第二个链接)
生产者与消费者之间是互斥关系。不能同时访问交易场所,所以我们加一把锁来协同两者。
我们不难猜出这个锁mutex在这里的含义,假设此时有两个消费者A,B都在等待资源(等待条件变量变为真)。此时生产者申请到了”锁”,并且生产了一个“商品”。紧接着释放了锁资源,并发送信号告诉消费者:“你们可以来买了”。
消费者A率先抢到了锁,并且买走了这个“商品”。之后消费者B申请到了锁,进入商场发现已经没有商品了,此时条件变量为假。消费者B会一直等到条件变量为真。但是此时锁在B身上,如果B不释放锁,并且一直等待的话,生产者因为

你可能感兴趣的:(Linux学习笔记,Linux学习之路,多线程,生产者与消费者,条件变量,多元信号量)