我想为我的系统增加FD_SETSIZE宏值。 有没有办法增加FD_SETSIZE所以选择不会失败
答案 0 :(得分:13)
我还建议尽可能使用poll
。并且存在几个"事件"处理诸如libevent或libev之类的库(或来自GTK的Glib的事件能力,或QtCore等)应该对您有所帮助。还有epoll之类的东西。而且您的问题与C10k
答案 1 :(得分:12)
根据标准,无法增加FD_SETSIZE
。一些程序和库(想到了libevent)尝试通过为fd_set
对象分配额外空间并将大于FD_SETSIZE
的值传递给FD_*
宏来解决此问题,但这是一个非常糟糕的主意,因为健壮的实现可以对参数执行边界检查,如果超出范围则中止。
我有一个应该始终有效的替代解决方案(即使标准不要求它)。而不是单个fd_set
对象,分配一个足够大的数组来保存您需要的最大fd,然后使用FD_SET(fd%FD_SETSIZE, &fds_array[fd/FD_SETSIZE])
等来访问该集合。
答案 2 :(得分:8)
用民意调查取代会更好(也更容易)。通常poll()是select()的简单替代品,并且不受UP_SETSIZE的1024的限制...
fd_set fd_read;
int id = 42;
FD_ZERO(fd_read);
FD_SET(id, &fd_read);
struct timeval tv;
tv.tv_sec = 5;
tv.tv_usec = 0;
if (select(id + 1, &fd_read, NULL, NULL, &tv) != 1) {
// Error.
}
变为:
struct pollfd pfd_read;
int id = 42;
int timeout = 5000;
pfd_read.fd = id;
pfd_read.events = POLLIN;
if (poll(&pfd_read, 1, timeout) != 1) {
// Error
}
您需要为pollfd结构包含poll.h。
如果你需要写和读,那么将事件标志设置为POLLIN | POLLOUT。
答案 3 :(得分:6)
为了使用大于FD_SETSIZE的fd_set
,可以像这样定义扩展名:
#include <sys/select.h>
#include <stdio.h>
#define EXT_FD_SETSIZE 2048
typedef struct
{
long __fds_bits[EXT_FD_SETSIZE / 8 / sizeof(long)];
} ext_fd_set;
int main()
{
ext_fd_set fd;
int s;
printf("FD_SETSIZE:%d sizeof(fd):%ld\n", EXT_FD_SETSIZE, sizeof(fd));
FD_ZERO(&fd);
while ( ((s=dup(0)) != -1) && (s < EXT_FD_SETSIZE) )
{
FD_SET(s, &fd);
}
printf("select:%d\n", select(EXT_FD_SETSIZE,(fd_set*)&fd, NULL, NULL, NULL));
return 0;
}
打印:
FD_SETSIZE:2048 sizeof(fd):256
选择:2045
<小时/> 为了打开超过1024个文件描述符,需要使用例如
ulimit -n 2048
来增加限制。
答案 4 :(得分:2)
实际上 IS 是一种在Windows上增加FD_SETSIZE的方法。它在winsock.h中定义,并且每个微软本身你可以通过在包含winsock.h之前简单地定义它来增加它。
http://support.microsoft.com/kb/111855
我一直这样做并没有遇到任何问题我使用的最大值是5000左右我正在开发的服务器