理论层面
1、环形队列的特性认识
- 环形队列采用数组模拟,用模运算来模拟环状特性
- 环形结构起始状态和结束状态都是⼀样的,不好判断为空或者为满,所以可以通过加计数器或者标记位来判断满或者空。另外也可以预留⼀个空的位置,作为满的状态
2、环形队列的生产消费模型
对于计算机而言,本质上只有两种资源:空间和数据。
- 环形队列的生产消费模型可以理解为一种固定存放数据的空间机制。在这个模型中,生产者申请空位置写入数据,而消费者从非空的位置获取数据。
3、环形队列的特性
-
互斥
当环形队列为“空”时,只有生产者能够进入并写入数据;当环形队列为“满”时,只有消费者能够进入并读取数据。这种机制保证了生产者和消费者之间的互斥性。 -
同步
当环形队列为“空”时,必须让生产者先进行生产操作;当环形队列为“满”时,必须让消费者先进行消费操作。这种机制体现了生产者和消费者之间的同步关系。
4、并发与追逐游戏
在环形队列不为空也不为满的情况下,生产者和消费者的关系就像一场在圆桌上的追逐游戏:
- 生产者不停地绕着圆桌,在每个空盘子上放置苹果。
- 消费者则紧跟其后,不停地从盘子中拿走苹果。
在这种情况下,生产者和消费者的操作是并发的,彼此独立且互不影响。
5、特殊情况
- 当消费者追上生产者时,说明消费者的消费能力较强,很快将圆桌上的苹果全部拿完,此时环形队列处于“空”的状态。
- 当生产者追上消费者时,说明生产者的生产能力较强,很快将圆桌上的苹果全部放满,此时环形队列处于“满”的状态。
由于环形队列的“空”和“满”状态会触发互斥与同步机制,因此消费者绝对不可能超越生产者。
6、资源需求与信号量设计
- 对于生产者来说,需要的是空间资源,因为生产者需要向空的位置写入数据。
- 对于消费者来说,需要的是物品资源,因为消费者需要从非空位置读取数据。
基于此,可以设计两个信号量:
- 空间信号量:用于表示可用的空闲空间。
- 物品信号量:用于表示已有的数据资源。
综上所述,生产者和消费者在同一位置时体现同步和互斥,而在不同位置时体现并发关系。
代码层面
1、生产者与信号量的操作逻辑
-
生产者对空间的 P 操作
生产者需要占用一个空闲空间来写入数据。因此,在生产之前,它会对空间信号量进行 P 操作(申请资源)。这表示生产者正在尝试获取一个可用的空间。 -
生产者对数据的 V 操作
当生产者完成数据写入后,它并不会释放自己占用的空间(即不会对空间信号量进行 V 操作),而是通过 V 操作增加数据信号量的值。这是因为生产者的核心任务是生成数据,并将数据提供给消费者使用。- 空间信号量:表示可用的空闲空间数量。
- 数据信号量:表示已生成的数据数量。
因此,生产者的操作逻辑可以总结为:
- 对空间信号量 P 操作:申请一个空闲空间。
- 对数据