5

我们正在使用 c++ 设计一个 p2p 应用程序,它使用 UDP 将语音传输到其他对等方。

我们正在线程中的缓冲区中捕获麦克风信号,while该线程在循环中捕获一秒钟的语音。对于在缓冲区中捕获的每一秒语音,它会将其拆分为数据包并发送到另一个对等方。现在我需要在目的地有一个适当的数据结构来应对实时传输。我将用于屏幕捕获的相同数据结构。这是我想到的两种使用队列的方法

  • 使用链表实现队列,该链表在图像的情况下维护OneSecVoice对象或对象的队列。Image

  • OneSecVoice使用或Image对象的静态数组实现队列

OneSecVoice/Image对象将包含数据包的总数,数据缓冲区为那个特定的Image/OneSecVoice

由于它是实时的,一个线程将连续扫描队列并通过弹出队列取出最新的完成Image/OneSecVoiceImage/OneSecVoice

所以选择使用链表实现队列或使用静态数组实现队列

我和我的朋友为此争论不休,所以我们决定在这里发帖。

4

4 回答 4

5

我会使用boost::circular_buffer。您将获得具有固定内存区域且没有意外内存分配的缓存优势。

为了实现最大效率,circal_buffer 将其元素存储在连续的内存区域中,然后启用:

  1. 使用固定内存,没有隐式或意外的内存分配。
  2. 从正面和背面快速恒定时间插入和移除元素。
  3. 元素的快速恒定时间随机访问。
  4. 适用于实时和性能关键的应用程序。

循环缓冲区的可能应用包括:

  • 存储最近收到的样本,在新样本到达时覆盖最旧的样本。
  • 作为有界缓冲区的底层容器(请参阅有界缓冲区示例)。
  • 一种存储指定数量的最后插入元素的缓存。
  • 高效的固定容量 FIFO(先进先出)或 LIFO(后进先出)队列,当已满时移除最旧(作为第一个插入)的元素。
于 2009-10-11T18:46:18.143 回答
3

也不执行。使用标准库中预先存在的实现:

std::queue<T, std::list<T> >
std::queue<T, std::deque<T> > // uses deque by default, by the way

您可以 typedef 这些以使交换两者变得非常容易:

template <typename T>
struct queue_list
{
    typedef typename std::queue<T, std::list<T> > value_type;
}

template <typename T>
struct queue_array
{
    typedef typename std::queue<T, std::deque<T> > value_type;
}

typedef queue_list<the_type>::value_type container_type; // use one
typedef queue_array<the_type>::value_type container_type;

现在配置文件并找到哪个更好。对于缓存,阵列可能具有更好的性能。

您可以使用boost 的池分配器来尝试从列表的快速插入和删除以及数组的缓存性能中受益:

typedef typename std::queue<T, std::list<T, boost::pool_allocator<T> > > value_type;

另一种尝试的结构是boost::circular_buffer,如fnieto 所建议的

template <typename T>
struct queue_buffer
{
    typedef typename std::queue<T, boost::circular_buffer<T> > value_type;
}    
于 2009-10-11T18:30:28.083 回答
1

如果接收端的唯一操作是退出队列,我真的看不出使用静态数组的意义,如果您需要对连续数据块或随机访问进行操作,这通常很有用。

我认为使用静态数组不会节省任何空间。当然,您正在为每个条目保存一个指针,但代价是分配了大量固定的内存块。如果您的队列有时会变得那么大,那么您可能需要链表提供的灵活性,因为它可以增长到任意大小。

如果您想限制它可以增长的大小,您可以在任一方案中执行此操作。

于 2009-10-11T18:32:50.230 回答
0

链表将是规范的方法,“使用静态数组实现队列”实际上是我的做法 - 以便重新组装 udp 数据包,然后可能将排序的数据传递给 LL 以便它被排序。您将如何跳舞“持续扫描队列并取出最新完成”,因为您不能将其塞入其中,因为 udp 可能会以意想不到的顺序出现。最新完成并不意味着“咖啡”出现在“豆类:”之后,所以你可能会在某个地方得到一些混乱的豆。

于 2009-10-11T19:00:55.587 回答