基于数组的有界缓冲区中的空元素
Empty element in array-based bounded buffer
我有一个典型的生产者/消费者问题。生产者的代码是这样的:
#define BUFFER_SIZE 10
while (true) {
/* Produce an item */
while (( (in + 1) % BUFFER_SIZE) == out)
; /* do nothing -- no free buffers */
buffer[in] = item;
in = (in + 1) % BUFFER_SIZE;
}
消费者是:
while (true) {
while (in == out)
; // do nothing -- nothing to consume
// remove an item from the buffer
item = buffer[out];
out = (out + 1) % BUFFER_SIZE;
return item;
}
这很好,但问题是,当前八个元素以及in=9
和out=0
被填充时,生产者坐在那里,不填充最后(第九)个元素。当例如in=4
和out=5
时也会发生这种情况。在每种情况下,都会有一个元素为空,并且即使有一个插槽仍然为空,队列也会显示为"已满"。
我可以想出一些复杂的检查,但我需要知道是否有一个干净的解决方案来填充整个队列。我尝试过先递增,然后再放入item
,但也遇到了类似的问题。(用-1
为in
和out
初始化也不起作用)。
请参阅维基百科关于这个主题的内容。最简单的解决方案似乎是:
- 始终保持一个插槽为空:如果
in == out
,则缓冲区为空;如果in == out - 1
,则缓冲区已满 - 用
num_unread_items
替换out
;执行简单数学运算从num_unread_items
和in
中检索out
但是存在与计数读取&写入操作(在单独的变量中或直接在in
和out
中);或者跟踪除了当前in
和out
之外的最后一次操作是读取还是写入,这允许您消除缓冲区已满/缓冲区已空的情况的歧义。
在大学的一堂操作系统开发课上,我有一位兼职老师声称,不可能有一个只使用软件的解决方案来使用缓冲区中的所有N个元素。我用我决定称之为赛道解决方案的东西证明了他错了(灵感来自于我喜欢跑赛道的事实)。
在赛道上,你不局限于400米的比赛;一场比赛可以包括一圈以上。如果两个跑步者并驾齐驱会发生什么在比赛中?你怎么知道他们是打成平手,还是一个跑者超过了另一个?答案很简单:在比赛中,我们不监控跑步者的位置在赛道上;我们监测每个跑步者走过的距离。因此,当两名选手并驾齐驱时,我们可以区分平局和一名选手搭接另一个。
因此,我们的算法有一个N元素数组,并管理2N个竞赛。在他们完成各自的2N比赛之前,我们不会将生产者/消费者的计数器重新设置为零。我们不允许生产商领先消费者一圈以上,也不允许消费者领先生产商。事实上,我们只需要监控生产者和消费者之间的距离。
代码如下:
Item track[LAP];
int consIdx = 0;
int prodIdx = 0;
void consumer()
{ while(true)
{ int diff = abs(prodIdx - consIdx);
if(0 < diff) //If the consumer isn't tied
{ track[consIdx%LAP] = null;
prodIdx = (prodIdx + 1) % (2*LAP);
}
}
}
void producer()
{ while(true)
{ int diff = (prodIdx - consIdx);
if(diff < LAP) //If prod hasn't lapped cons
{ track[prodIdx%LAP] = Item(); //Advance on the 1-lap track.
prodIdx = (prodIdx + 1) % (2*LAP);//Advance in the 2-lap race.
}
}
}
我最初解决这个问题已经有一段时间了,所以这是我最好的回忆。希望我没有忽略任何错误。希望这能有所帮助!
- Mongodb c++驱动程序:如何查询元素的数组
- C++字符*缓冲区的大小
- 将数组作为参数传递给函数安全吗?作为第三方职能部门,可以探索他们想要的之外的其他元素
- 使用strcpy将char数组的元素复制到另一个数组
- 使用不带参数的函数访问结构元素
- 给定n个元素的m个集合.在C++中找到出现在最大集合数中的元素
- C++如何通过用户输入删除列表元素
- 为什么msgrcv()将垃圾字符馈送到缓冲区
- lower_bound()返回最后一个元素
- 基于多个条件处理地图中的所有元素
- 调整大小后指向元素值的指针unordered_map有效?
- 将指针作为缓冲区传递到第一个字符串元素
- 跳过元素缓冲区中的索引
- 如何在协议缓冲区中初始化排序和过滤重复的元素
- Direct3D 多个顶点缓冲区,非交错元素
- 基于数组的有界缓冲区中的空元素
- 具有相同元素的两个常量缓冲区
- 如何初始化协议缓冲区中的重复元素
- 仅修改VBO缓冲区数据的特定元素类型
- 访问字符串映射和Boost循环缓冲区的元素