1

短篇故事

我需要将传入消息数据添加到固定长度的缓冲区。
如果缓冲区已满,则用新的替换最旧的消息数据(或缓冲区中最旧的字节)。这是某种队列。
如何实现这种队列?
程序是用 C 语言编写的,我对 C 语言知之甚少(更像是没有)。

很长的故事

我有一个从设备接收消息的程序。
此消息可能具有可变长度并具有关联的 Id。
目前,该程序仅保留每个 Id 收到的最新消息。
此消息由程序内部保存,仅在有配置或用户发送命令(实时)以获取给定 ID 的接收消息时才显示给用户。
现在需要保留给定 Id 的几条收到的消息(不仅仅是最后一条)并返回它们。它们不需要单独退回。它们可以在一个块中全部返回(将多个消息视为设备正在返回的一段内存数据)。
目前有一个固定长度的缓冲区来保存接收到的消息和一个变量来跟踪接收到的消息长度。
所以我正在考虑使用现有的缓冲区并继续向其中添加新消息。如果另一条消息出现并且缓冲区上没有更多空间,那么我应该覆盖最旧的消息数据。有点像排队。
尤其是实现这种队列的最后一部分是我需要更多帮助的地方。
该程序是用 C 编写的,不是我做的,而且我对 C 的了解有限(不是说不存在 :)
我真的应该先学习 C,但现在没有时间了 :) 我已经完成了 C#, Java、Javascript 等等。

对管理这个队列之王有什么帮助吗?

谢谢

4

1 回答 1

1

在这种情况下,循环缓冲区会有所帮助,只需稍加修改即可在缓冲区满时踢出最旧的条目。想象一下,你有一些这样typedef struct msg {...} msg的数组message[N],然后你管理两个索引,int in, out它们都初始化为 0。

虽然out != in您可以从该数组中读取消息。您使用某种形式in的. 到目前为止,这与任何其他循环缓冲区没有什么不同。outout = (++ out) % N;

现在,让我们解决您在缓冲区已满的情况下替换最旧消息的问题,即(in + 1) % N == out当您即将执行插入时。使用循环缓冲区,这现在非常简单。为了腾出空间,out向前推一个,让你in无论如何都增加,然后你插入:

if (((in + 1) % N) == out)
{ 
    out = (++ out) % N;
}
in = (++ in) % N;
message[in] = incoming_msg;

向前推动读者的索引out,允许该位置用于最新消息。

于 2013-01-27T00:06:14.723 回答