问题描述
我需要一个支持索引的FIFO结构。每个元素是一个数据的数组,它保存在我正在读取的设备上。 FIFO具有恒定大小,并且在启动时每个元素都被清零。
I need a FIFO structure that supports indexing. Each element is an array of data that is saved off a device I'm reading from. The FIFO has a constant size, and at start-up each element is zeroed out.
这里有一些伪代码来帮助理解这个问题:
Here's some pseudo code to help understand the issue:
Thread A (Device Reader):
1. Lock the structure.
2. Pop oldest element off of FIFO (don't need it).
3. Read next array of data (note this is a fixed size array) from the device.
4. Push new data array onto the FIFO.
5. Unlock.
Thread B (Data Request From Caller):
1. Lock the structure.
2. Determine request type.
3. if (request = one array) memcpy over the latest array saved (LIFO).
4. else memcpy over the whole FIFO to the user as a giant array (caller uses arrays).
5. Unlock.
请注意,FIFO不应该在线程B中更改,调用者应该获得一个副本,因此,pop是破坏性的数据结构不一定会在没有中间副本的情况下工作。
Note that the FIFO shouldn't be changed in Thread B, the caller should just get a copy, so data structures where pop is destructive wouldn't necessarily work without an intermediate copy.
我的代码也有一个boost依赖,我在其他地方使用了一个lockfree spsc_queue。说到这里,我不明白这个队列对我这里工作,因为在某些情况下需要工作作为一个LIFO,还需要memcpy在整个FIFO的时候。
My code also has a boost dependency already and I am using a lockfree spsc_queue elsewhere. With that said, I don't see how this queue would work for me here given the need to work as a LIFO in some cases and also the need to memcpy over the entire FIFO at times.
我也考虑过一个简单的 std :: vector
,但是我担心在我不断推送和弹出时的性能。
I also considered a plain std::vector
, but I'm worried about performance when I'm constantly pushing and popping.
推荐答案
我建议你使用 boost :: circular_buffer
支持随机存取迭代,在开始和结束时的恒定时间插入和擦除。您可以将其用作 push_back()
的FIFO,读取 back()
以保存和迭代整个容器通过 begin(),end()
或使用 operator []
。
I would suggest you to use boost::circular_buffer
which is a fixed size container that supports random access iteration, constant time insert and erase at the beginning and end. You can use it as a FIFO with push_back()
, read back()
for the latest data saved and iterate over the whole container via begin(), end()
or using operator[]
.
但是在启动时元素不会被清零。它在我看来有一个更方便的界面。容器最初为空,插入将增加大小,直到达到最大大小。
But at start-up the elements are not zeroed out. It has in my opinion an even more convenient interface. The container is empty at first and insertion will increase size until it reaches max size.
这篇关于选择适当的FIFO数据结构的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!