2

我正在开发一个 MMO 游戏服务器项目,但遇到了问题。那是 select() 方法的限制。我想用一个线程处理超过 1024 个套接字 I/O。我想用单线程来做这个,因为我试图做一个多线程处理系统。该系统创建了 3 个线程(例如在 4 核处理器中;1 个是主线程,3 个是 select() 处理程序)来处理 select() 方法,但又出现了另一个问题,现在我们的限制已达到 3072 (1024 * 3)这不是解决方案!有了这个想法,我想制作一个非阻塞套接字系统,在这个系统中,我在 1 个单线程中调用了 2 个不同的选择方法,就像这样;“选择()选择()”。它们按顺序返回,我可以按顺序处理它们。但我认为还有一个问题。如果我想实现一个像“

注意:我不想使用 poll-epoll-wsapoll 等(poll 无法处理微秒,它不如 select 快!)和 libevent 之类的 3rd 方库(我想自己制作!)

最终解决方案(我认为):我不需要为 I/O 操作处理纳秒,因为处理它没有意义。轮询是处理超过 1024 个套接字 I/O 的好方法。我会研究一些东西来理解 MMO 系统。最后一个是我会做一些测试,在我问问题之前我会尝试一些东西:) 谢谢!

编辑:我是这个问答平台的新手。在给出否定点后,你能告诉我我的问题有什么问题吗?:)

4

2 回答 2

7

使用select这么多(数千个)连接从根本上是错误的。虽然select当您只有很少数量的套接字(可能是几十个)时通常会更快,但它可以可怕地扩展到数千甚至更多。我所知道的任何地方,都会select随着连接数线性减慢(甚至比这更糟,但我不会详细说明。)

Evenpoll并没有比select扩展到数千个连接更好。select它对您可以轮询的文件描述符的数量没有(低)限制,但它仍然与连接数呈线性关系。

您真正应该使用的是特定于平台的工具,例如epollkqueue。它们的扩展性非常好(通常是O(1),),但显然它们不可移植。

我强烈建议您考虑像libev之类的东西,它是一种可移植的、经过高度测试的、围绕特定平台的设施和服务的精简包装器。

这是因为特定于平台的方法(例如selectpollepollkqueueI/O 完成端口、事件端口等)彼此不同,并且它们都不能在超过一个或两个平台上使用,或者它们的限制和详细信息他们的行为略有不同。这些设施甚至可能从一个操作系统版本更改为下一个版本(例如epoll在 Linux 2.6.9、IIRC 上)。

即使您不关心代码的可移植性或面向未来的问题,这样的库也可以为您提供更多功能和更好的界面。

您可以尝试的另外两个库是libevent(更大更慢,但功能更多)和libuv(如果您需要 Windows 可移植性。)

于 2013-07-04T00:47:22.630 回答
4

鉴于您设定的要求,您的问题没有解决方案。

  • 克服(1024) 文件描述符select()限制的正常方法是使用(或更好的替代品 epoll 和 kqueue),但您拒绝了该选项。FD_SETSIZZEpoll()
  • select()否则,您总是可以通过在具有不同文件描述符集的不同线程中并行调用多次来克服该问题......但您也拒绝了该选项。

我不相信真的可以有任何其他的解决方案!

也许您应该解释为什么poll()et al 选项和 thread 选项都不合适。您的要求似乎是没有正当理由的人为限制。

于 2013-07-04T00:19:33.460 回答