2

我正在编写一个消息队列,旨在通过套接字进行操作,出于各种原因,我希望队列内存存在于用户空间中,并有一个线程将队列排入各自的套接字。

消息将是内存的小块(可能在 4 到 4K 字节之间),所以我认为避免使用 malloc() 内存是避免碎片的必要条件。

操作模式是用户调用类似 send(msg) 的东西,然后将消息复制到队列内存中,并在方便的时间通过套接字发送。

我的问题是,是否有一种“好”的方法可以将可变大小的数据块存储在 std::queue 或 std::vector 之类的东西中,或者我是否必须走一条将内存池放在一起并处理我的自己配置出来的那个?

4

4 回答 4

3

您可以创建一个大的循环缓冲区,将数据从块复制到该缓冲区,并将对存储{start pointer, length}在队列中。由于块的分配顺序与它们被消耗的顺序相同,因此检查重叠的数学应该相对简单。

如今,内存分配器已经变得相当好,所以如果基于“普通”分配器的解决方案表现出相当的性能,我不会感到惊讶。

于 2012-06-07T14:54:16.367 回答
1

您可以将内存池负担委托给Boost.Pool

于 2012-06-07T14:45:10.443 回答
1

如果它们低于 4K,您可能根本没有碎片。你没有提到你要运行你的应用程序的操作系统,但如果是 Linux 或 Windows,它们可以处理这种大小的块。至少您可以在编写自己的池之前检查这一点。例如看这个问题:关于小块分配器的问题

于 2012-06-07T14:55:27.083 回答
0

除非您希望有很多排队的数据包,否则我可能只是创建一个 池vector<char>,每个池中保留(比如说)8K。处理完一个数据包后,请回收该向量而不是将其丢弃(即,将其放回池中,准备再次使用)。

如果您确实确定您的数据包不会超过 4K,那么您显然可以将其减少到 4K 而不是 8K——但假设这是一个长期运行的程序,您可能从最小化重新分配中获得更多收益,而不是从最小化大小中获得更多的单个向量。

一个明显的替代方法是在分配器级别处理此问题,因此您只是重用内存块而不是重用向量。这将使调整内存使用变得更容易一点。我仍然会预先分配块,但只有几个大小——比如 64 字节、256 字节、1K、2K、4K(可能还有 8K)。

于 2012-06-07T14:57:20.593 回答