我正在开发一个MMO游戏服务器项目,我遇到了问题。这是select()方法的限制。我想用一个线程处理超过1024个套接字I / O.我想用单线程做这个,因为我试图建立一个多线程处理系统。该系统创建了3个线程(例如4核处理器; 1个是main,3个是select()处理程序)处理select()方法,但是还有另一个问题,现在我们的限制已经变为3072(1024 * 3)那不是解决方案!在那个想法之后,我想创建一个非阻塞套接字系统,用这个系统我在这样的单个线程中调用了2个不同的select方法; “select()select()”。它们按顺序返回,我可以按顺序处理它们。但我认为还有另一个问题。如果我想实现一个像“while(true){select()select()}”和select()方法(非阻塞)retun的线程,我会像空的“while(true)”块一样重载CPU。如果我想进行select()超时,我无法实时处理底部select()。现在我无法为此制作算法。有人可以帮我这个吗?
注意:我不想使用poll-epoll-wsapoll等。 (轮询无法处理微秒,它不像选择快!) 和像第三方图书馆一样的解放(我想自己制作!)
最终解决方案(我认为):我不需要为I / O操作处理纳秒,因为没有意义来处理它。轮询是处理超过1024个套接字I / O的好方法。我将研究一些用于理解MMO系统的东西。最后一个是我会做一些测试,在问一个问题之前我会尝试一些事情:)谢谢!
编辑:我是这个Q& A平台的新手。在给出负面观点后,你能告诉我我的问题有什么问题吗? :)
答案 0 :(得分: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可移植性。)
答案 1 :(得分:4)
根据您设置的要求,您的问题无法解决。
select()
(1024)文件描述符FD_SETSIZZE
限制的正常方法是使用poll()
(甚至更好的替代epoll和kqueue),但是你拒绝了选项。select()
来解决此问题...但您也拒绝了该选项。我不相信可以有任何其他解决方案!
也许您应该解释为什么poll()
等选项和线程选项都不合适。您的要求似乎是没有正当理由的人为限制。