C ++ IOCP服务器容器信息

时间:2012-09-11 06:45:53

标签: c++ iocp

我一直在想一些关于如何在维护KISS的同时使用IO类型的架构实际包含大量连接的想法。通过网络上的示例,似乎大多数人使用带有CONTAINING_RECORD的双/单链表。而且,作为IO服务器中的新手(尽管每天都在进步),我也使用链表容器来构建IO架构。

我的问题是,为什么我只能构建一个大型数组并使用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.

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

2 个答案:

答案 0 :(得分:1)

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

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

答案 1 :(得分:0)

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

在之前的工作中,我花了大部分时间在一个巨大的多线程C ++服务器上工作,该服务器在其Windows版本中使用了IO完成端口(Solaris后端使用/ dev / poll,这在几个要点中并没有那么不同) 。那个存储了与STL之前的map类似结构的连接相关数据结构,使用文件描述符作为键值。因此,每当我们在连接上获得事件时,我们就可以通过IO层传递给我们的描述符来查找其相关的数据结构。新的连接很容易处理 - 只需在字典中添加一个条目 - 封闭的连接也可以非常简单地清理。

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

基本的总结是,我们发现一个适当设计的字典类对于这类事情非常有用。