多线程IOCP服务器中重叠结构的存储和管理 [英] storage and management of overlapped structure in multithreaded IOCP server

查看:124
本文介绍了多线程IOCP服务器中重叠结构的存储和管理的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用链接列表存储重叠结构是个好主意吗?

Is it good idea to use LINKED LIST to store overlapped structure?

我重叠的结构看起来像这样

my overlapped structure looks like this

typedef struct _PER_IO_CONTEXT 
{

  WSAOVERLAPPED               Overlapped;
  WSABUF                      wsabuf;
  ....
  some other per operation data
  ....
  struct _PER_IO_CONTEXT      *pOverlappedForward;
  struct _PER_IO_CONTEXT      *pOverlappedBack;

 } PER_IO_CONTEXT, *PPER_IO_CONTEXT;

当iocp服务器启动时,我在链接列表中分配(例如)5000个.该列表的开始存储在全局变量PPER_IO_CONTEXT OvlList中.我必须补充一点,仅在必须将数据发送到所有连接的客户端的情况下,才使用此链接列表. 当发布Wsasend或GQCS收到通知时,链接列表将更新(我使用EnterCriticalSection进行同步). 在此先感谢您提供的提示,意见和建议,以更好地存储(缓存)重叠结构.

When iocp server starts i allocate (for example) 5000 of them in Linked List. The start of this list is stored in global variable PPER_IO_CONTEXT OvlList. I must add that i use this linked list only in a case when i have to send data to all connected clients. When Wsasend is posted or GQCS gets notification, linked list is updated( i use EnterCriticalSection for synchronization ). Thanks in advance for yours tips, opinions and suggestions for better storage(caching) overlapped structure.

推荐答案

我假设建议的用例是您希望缓存每个操作"的重叠结构,以避免重复分配和释放动态内存,这可能导致分配器上的争用和堆碎片.

I assume the proposed use case is that you wish to cache the "per operation" overlapped structure to avoid repeated allocation and release of dynamic memory which could lead to both contention on the allocator and heap fragmentation.

使用单个池"将争用从使用用于分配和销毁重叠结构的分配器在所有线程之间争用"减少到在所有发出或处理I/O操作的线程之间的争用"一件好事.没错,您需要围绕访问进行同步,最好以临界区或以独占模式使用SRW锁(对于无竞争访问而言,后者要快一些).

Using a single 'pool' reduces the contention from 'contention between all threads using the allocator that is used for allocating and destroying the overlapped structures' to 'to contention between all threads issuing or handling I/O operations' which is usually a good thing to do. You're right that you need to synchronise around access, a critical section or perhaps a SRW lock in exclusive mode is probably best (the later is fractionally faster for uncontended access).

在长时间运行的系统中,减少堆碎片也是值得的.

The reduction in heap fragmentation is also worth achieving in a long running system.

使用标准"非侵入性列表(例如std::deque)起初似乎是显而易见的选择,但是非侵入性集合的问题在于它们倾向于为每个操作分配和取消分配内存(因此您回来了)到您的原始争论).恕我直言,更好的方法是在每个重叠的结构中放置一个指针,然后将它们简单地链接在一起.这不需要在访问池时分配或释放额外的内存,这意味着您的争用将回落到仅使用该池的线程上.

Using a 'standard' non invasive list, such as a std::deque looks like the obvious choice at first but the problem with non invasive collections is that they tend to allocate and deallocate memory for each operation (so you're back to your original contention). Far better, IMHO, to put a pointer in each overlapped structure and simply chain them together. This requires no additional memory to be allocated or released on pool access and means that your contention is back down to just the threads that use the pool.

我个人发现,对于池(自由列表),我只需要一个按操作结构的单链接列表(实际上只是一个堆栈),如果我要维护使用中"列表,则需要一个双链接列表.有时有用的每次操作"数据(尽管我现在不这样做了.)

Personally I find that I only need a singly linked list of per-operation structures for a pool (free list) which is actually just a stack, and a doubly linked list if I want to maintain a list of 'in use' 'per-operation' data which is sometimes useful (though not something that I now do).

然后,下一步可能是拥有多个池,但这取决于系统的设计以及I/O的工作方式.

The next step may then be to have several pools, but this will depend on the design of your system and how your I/O works.

如果对于给定的连接可以有多个挂起的发送和接收操作,则在连接级别上有一个小的池可能会很有用.这可以大大减少单个共享池的争用,因为每个连接将首先尝试使用每个连接池,如果每个连接池为空(或已满),则退回到使用全局池.这往往导致对全局池锁定的争用减少得多.

If you can have multiple pending send and receive operations for a given connection it may be useful to have a small pool at the connection level. This can dramatically reduce contention for your single shared pool as each connection would first attempt to use the per-connection pool and if that is empty (or full) fall back to using the global pool. This tends to result in far less contention for the lock on the global pool.

这篇关于多线程IOCP服务器中重叠结构的存储和管理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆