我正在使用一个带有写索引和读索引的数组来实现一个简单的FIFO队列。在递增写入和读取索引时,我会使用通常的MOD ArraySize。 有没有办法区分队列满和队列空条件(wrIndex == rdIndex)而不使用任何额外的queuecount,也没有浪费任何数组条目,即。如果(WrIndex + 1)MOD ArraySize == ReadIndex
,则队列已满答案 0 :(得分:1)
我会使用'wasting'数组条目来检测队列满状态,特别是如果你正在处理作为生产者和消费者的不同线程/任务。有另一个标志跟踪这种情况增加了保持一致性所需的锁定,并增加了某种引入竞争条件的bug的可能性。如果您不能使用关键部分(正如您在评论中提到的那样)以确保事物处于同步状态,则更是如此。
你至少需要一点点来跟踪那个条件,这可能至少意味着一个字节。假设你的队列包含ints
,你只需要节省3个字节的RAM,你就会咀嚼几个字节的程序图像(这可能不那么珍贵,所以这可能无关紧要)。如果在用于存储其他标志位的字节中保留一个标志位,那么您还必须以线程安全的方式处理设置/测试/清除该标志位,以确保其他位不会被破坏。
如果你正在排队字节,那么你可能什么都不保存 - 你可以认为sentinel元素是你必须放在其他地方的标志。但是现在你必须有 no 额外的代码才能处理这个标志。
请仔细考虑是否真的需要额外的队列项,并记住如果你正在排队字节,那么额外的队列项可能不是真正的额外空间
答案 1 :(得分:1)
您可以使用读取索引和队列计数,而不是读取和写入索引。从队列计数中,您可以轻松判断队列是否为空。写入索引可以计算为(读取索引+队列计数)mod array_size。
答案 2 :(得分:0)
队列计数有什么问题?听起来你要求最高的效率和最小的逻辑,虽然我会这样做,但我认为我仍然使用队列计数变量。否则,另一个可能的解决方案是使用链表。内存使用率低,删除第一个元素很容易,只需确保你有指向列表头部和尾部的指针。
答案 3 :(得分:0)
基本上你只需要一个额外的位来表示队列当前是空的。你可以把它藏在某个地方,例如,在你的一个索引中最重要的位(而不是在需要仅对数组中的实际索引进行处理的地方创造性地对低位进行AND)。
但说实话,我会首先使用队列计数,但如果我真的需要那个空间,那就只能削减它,而不是忍受一点点摆弄。