处理超过 1024 个套接字?

问题描述 投票:0回答:2

我正在开发一个 MMO 游戏服务器项目,但遇到了问题。这是 select() 方法的限制。我想用一个线程处理超过 1024 个套接字 I/O。我想用单线程来做这个,因为我尝试过制作一个多线程处理系统。该系统创建了 3 个线程(例如在 4 核处理器中;1 个是主线程,3 个是 select() 处理程序)来处理 select() 方法,但又出现了另一个问题,现在我们的限制已达到 3072 (1024 * 3)这不是解决办法!在这个想法之后,我想制作一个非阻塞套接字系统,在这个系统中,我在 1 个单线程中调用了 2 个不同的 select 方法,如下所示; “选择()选择()”。他们按顺序返回,我也可以按顺序处理。但我认为还有一个问题。如果我想实现像“while(true){ select() select()}”这样的线程和 select() 方法(非阻塞)重调,我会像空的“while(true)”块一样使 CPU 过载。如果我想使 select() 超时,我无法实时处理底部 select() 。现在我无法为此制定算法。有人可以帮我解决这个问题吗?

注意:我不想使用 poll-epoll-wsapoll 等。 (poll 无法处理微秒,它不如 select 快!) 和 libevent 像第 3 方库(我想让我的拥有!)

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

编辑:我是这个问答平台的新手。给负分后你能告诉我我的问题有什么问题吗? :)

c++ c sockets networking posix-select
2个回答
7
投票

使用

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

即使是

poll
在扩展到数千个连接方面也并不比
select
好多少。它对可以轮询的文件描述符数量没有
select
的(低)限制,但它仍然随连接数量线性扩展。

您真正应该使用的是特定于平台的工具,例如

epoll
kqueue
。它们的扩展性非常好(通常O(1)),但显然它们不可移植。

我认真建议您考虑像 libev 这样的东西,它是一个可移植的、经过高度测试的、围绕特定平台的设施和服务的薄包装。

这是因为特定于平台的方法(例如

select
poll
epoll
kqueue
、I/O 完成端口、事件端口等)彼此不同,并且它们都不可用不止一两个平台,或者它们的限制和行为细节略有不同。这些设施甚至可能从操作系统的一个版本更改为下一个版本(例如 Linux 2.6.9、IIRC 上的
epoll
。)

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

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


4
投票

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

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

我不相信真的还有其他解决方案!

也许您应该解释为什么

poll()
等选项和线程选项都不合适。您的要求似乎是没有道理的人为限制。

© www.soinside.com 2019 - 2024. All rights reserved.