在linux和c环境中可以编写一个服务器来接受"接受"在一个或多个IP地址和工作(recv / send)上使用"选择"以及超过FD_SETSIZE客户端(套接字)。 (不是民意调查)。我使用线程或上下文进行探测,但我还没有找到解决方案。存在解决方案?
答案 0 :(得分:2)
您应该考虑使用poll(2)而不是旧select(2),因为FD_SETSIZE
是编译时常量。
(增加FD_SETSIZE
是不合理的:你需要重新编译内核,可能是C库和使用select
的所有库 - 实际上这几乎意味着从源代码重建你的发行版 - ,你当然需要深入了解你真正不想关心的实现细节;这是应该避免select
的原因之一; poll
可以处理更多的文件描述符,等等重要的是可以处理一小组文件描述符,其中一些具有很大的数值,这在大多数多线程方法中都是必不可少的)
另请阅读C10k problem(由Some programming dude评论)。如果你有这么多的联系,你应该小心设计你的程序,有很多RAM。考虑使用一些现有的事件循环库(libev,libevent,...),查看epoll(7),libcurl(HTTP客户端库) ,libonion(HTTP服务器库)。或者将您的应用程序设计为FastCGI一个(在某些现有 Web服务器之上)。或者将其设计为连接到某些load balancing HTTP代理等的一些内部HTTP服务器(在几台机器上运行)...或者使用一个(或几个)数据库系统(也许{{3 }})。
如果您正在编写新的应用程序,我建议保持实用性。仔细编码,但考虑到有限的扩展。当(并且仅当)您拥有数百万用户和数十万个同时连接时,您将获得资金来重新设计它(如此大规模)(并且您还需要在硬件上花费很多)。而在那个大规模FD_SETSIZE
只是一个微问题(你会遇到很多其他问题)。
如果您今天需要解决C10k(或C100K)问题,请确保获得足够的开发人员权力 - 您可能需要一支合格开发人员团队至少工作一年。
但我还没有找到解决方案。
因为你的约束可能没有。
另请阅读distributed databases(可免费下载,有点旧)和Advanced Linux Programming。要了解多线程,请阅读一些好的syscalls(2)。避免使用大量线程(在强大的机器上最多可能需要几十个线程)。
您应改善您的问题以激励它并提供您的背景和您正在处理的实际问题。你的“我必须使用选择”的座右铭与某些pthread tutorial的气味非常相似。如果使用select
非常重要,请接受它的限制:最大fd为1024(FD_SETSIZE
的值),因此请与您的经理或客户讨论该限制。如果你选择使用select
,那就是设计错误,你需要努力重构你的代码。
答案 1 :(得分:1)
不是select()
,如果这意味着非阻塞模式并选择每个频道。每个连接使用一个线程的阻塞模式根本不依赖于FD_SETSIZE,也不依赖于异步I / O.
答案 2 :(得分:1)
FD_SETSIZE
可以在包含任何内容之前重新定义,select
将使用该设置大小。这从未标准化,可能不适用于某些系统。它也很危险,因为你需要非常确定在任何地方使用的正确定义可能比它看起来更难。
没有可移植的方法,这就是为什么没有新代码应该使用select
。 poll
作为select
的替代已经存在了几十年,因为它解决了这个以及其他选择的问题。不要使用select
,这是一个非常糟糕的界面。
对于更高吞吐量的守护进程,您甚至应该避免使用poll
并使用其中一个较不便携的接口,如kqueue
或epoll
,或者甚至更好地使用包含这些接口的库像libevent或libev等。