2012-09-11 45 views
1

我在头脑中传递了一些想法,关于如何在维护KISS的同时实际包含大量使用IO类型体系结构的连接。通过网络上的例子,似乎大多数使用CONTAINING_RECORD的双/单链表。而且,作为IO服务器的新手(尽管每天都在改进),我也使用链接列表容器来实现IO体系结构。C++ IOCP服务器容器信息

我的问题是,为什么不能为我的连接使用单/双链表,我为什么不能建立一个大数组并使用CONTAINING_RECORD?我可以使用STL矢量吗?这会起作用吗?另外,什么是其他类型的容器与大规模IO服务器的最佳配合。

我正在为我的游戏服务器重新编写服务器架构(经过多次修改),并且希望这次能够朝着正确的方向前进,因为id不必在不久的将来再次重写它。

谢谢你的时间,并回复。

编辑:目前我的服务器架构(简单地说):

Main thread listening and accepting -> Pass over the socket into a container. 
Worker threads(2-3) grab IO events for the container of sockets. 
Worker threads Read/Write Data on that container. 

主线程和工作线程都使用一个链表。我想摆脱这一点。

+0

如果您使用'select'或'poll'来检查连接状态,您可能还想考虑'std :: unordered_map',并将套接字描述符作为关键字。当然,你可以将容器组合起来,例如使用'std :: map'作为'std :: shared_ptr'的快速套接字查找作为指向另一个容器中实际结构的数据。 –

+0

@JoachimPileborg在Unix上,''select'或者'poll'(或者更好,'epoll','kqueue')是一个好主意,或者没有IOCP的WinCE,但@Ohmages是正确的关注IOCP的,它是在Windows上执行可伸缩服务器的方式。 – asveikau

+0

@Ohmages - 如果有多个线程耗尽IOCP,我将远离向量,重新分配可能会改变跨线程同步的痛苦地址。 – asveikau

回答

1

您的“连接列表”可能会从任何位置删除,而不仅仅是结束。对于std::vector,删除中间的元素是O(N)操作,但对于链接列表,它可以是O(1)。 (对于单链表,这不是微不足道的,可能需要一个不方便的API)。

std::map可能是一个有趣的选择,因为它提供了O(log N)查找和删除元素。

+0

你会建议地图还是unordered_map? – User

+0

在第一次迭代中不会担心。这在一定程度上取决于I/O架构。 – MSalters

+0

我可以使用WSAOVERLAPPED(的结构)作为地图的has键吗? – User

0

与所有的数据结构一样,它很大程度上取决于您想要用它做什么。

在以前的工作中,我花了大部分时间在一个大型多线程C++服务器上工作,该服务器在其Windows版本中使用了IO完成端口(Solaris后端使用的/ dev/poll,这在几个基本要素中并不相似)。那个存储连接相关的数据结构在类似于STL之前的类似map的结构中,使用文件描述符作为键值。因此,无论何时我们在连接上发生事件,我们都可以通过IO层递交给我们的描述符来查找它的相关数据结构。新的连接很容易处理 - 只需在词典中添加条目即可 - 关闭的连接也可以很轻松地清理干净。

当然,必须注意跨线程访问这些结构和操作顺序 - 因为IO本质上是有效的,所以操作的顺序是至关重要的。幸运的是,IOCP不会在另一个线程上为同一个套接字提供另一个事件,除非将套接字放回到CP中,但Solaris实现还必须保留一个将文件描述符链接到工作线程的结构,以确保我们仅处理每个套接字一次一个事件,并严格排列,我们还尝试将套接字的后续事件注入到同一个线程中,以避免必须将套接字的结构切换到另一个处理器,这对缓存命中率来说是一场灾难。

虽然基本的总结是我们找到了一个设计合理的字典类,对于这类事情来说是非常有用的。

+0

我对服务器的工作方式非常感兴趣,能否详细解释一下?主服务器是一个IOCP,它接收IO,然后将IO数据(即猜测套接字ID?)发送到Solaris,它使用套接字的键(使用map)查找数据?如果是这样的话,你是如何处理Solaris上的数据操作的?你是否只是发送回IO信息发送回客户端(和多个客户端,如果适用?) – User

+0

它是同一台服务器 - 它只在Windows和Solaris上运行,因此有两个套接字级IO层。因此,当在Windows上运行时,服务器通过IOCP接收数据,在地图中查看套接字,检索必要的数据结构,并使用它们将可以推入队列以供线程池处理的对象放在一起。 –