实时应用程序的数据结构

时间:2009-10-11 18:14:11

标签: c++ sockets p2p data-structures

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

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

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

  • 使用OneSecVoiceImage个对象的静态数组实现队列

对于该特定OneSecVoice/Image

Image/OneSecVoice个对象将包含数据包总数,数据包缓冲区

通过从队列中弹出Image/OneSecVoice,一个线程将实时持续扫描队列取出最新完整 Image/OneSecVoice

选择哪个使用链接列表实现队列使用静态数组实现队列

我和我的朋友正在争吵,所以我们决定在这里发帖。

4 个答案:

答案 0 :(得分:4)

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

  

为了达到最大化   效率,circular_buffer存储   它的元素在一个连续的区域   内存,然后启用:

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

    可能的应用   circular_buffer包括:

         
        
    • 最近收到的存储   样本,在新样本到达时覆盖最旧的样本。
    •   
    • 作为潜在的   有界缓冲区的容器(见   有界缓冲区示例)。
    •   
    • 一种存储指定数量的缓存   最后插入的元素。
    •   
    • 高效的固定容量FIFO(First In,First   Out)或LIFO(后进先出)   删除最旧的队列   (在第一次插入时)元素已满。
    •   

答案 1 :(得分:3)

不执行任何一项。使用标准库中预先存在的实现:

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

你可以输入这些来解决这两个问题非常容易:

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's pool allocator尝试获取列表快速插入和删除的好处,以及数组的缓存性能:

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

另一种尝试的结构是boost::circular_buffersuggested by fnieto

template <typename T>
struct queue_buffer
{
    typedef typename std::queue<T, boost::circular_buffer<T> > value_type;
}    

答案 2 :(得分:1)

如果接收端的唯一操作是从队列中弹出,我真的没有看到使用静态数组的意义,如果你需要对大量的连续数据进行操作或者随机访问。

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

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

答案 3 :(得分:0)

链接列表将是规范方法,“使用静态数组实现队列”实际上是我如何去做 - 以便重新组装udp数据包,然后可能将顺序数据传递给LL,以便它被命令。你怎么跳舞“连续扫描队列并取出最新的完整”,因为你不能把它塞进去,因为udp可能会出现意料之外的顺序。最新完成并不意味着“咖啡”出现在“豆类型”之后,所以你可以在那里找到一些混淆的咖啡豆。