我想增加我的系统的FD_SETSIZE宏值。是否有任何方法可以增加FD_SETSIZE,以便select不会失败
我想增加我的系统的FD_SETSIZE宏值。是否有任何方法可以增加FD_SETSIZE,以便select不会失败
FD_SETSIZE
。一些程序和库(例如libevent)尝试通过为fd_set
对象分配额外空间并传递大于FD_SETSIZE
的值给FD_*
宏来解决这个问题,但这是一个非常糟糕的想法,因为强大的实现可能会对参数进行边界检查,并在参数超出范围时终止操作。fd_set
对象,而是分配足够大的数组以容纳所需的最大fd,然后使用FD_SET(fd%FD_SETSIZE, &fds_array[fd/FD_SETSIZE])
等访问集合。bits/select2.h
。每当激活_FORTIFY_SOURCE
时,它都会被使用,并且它积极检查fd号码是否超出内部常量(不是你错误地声称可以修改的公共FD_SETSIZE
),并且如果fd号码超出范围就会终止程序(合法,因为UB被调用)。 - R.. GitHub STOP HELPING ICE使用轮询(poll)替换掉 select() 会更好(也更容易)。一般来说,poll() 是select()的简单替代方案,并且不受 FD_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
}
你需要包含poll.h头文件以使用pollfd结构体。
如果你需要进行读写操作,则需要将events标志设置为POLLIN | POLLOUT。
#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
select:2045
ulimit -n 2048
来增加限制。
poll()
是正确的方法。 - edamFD_SETSIZE
。它在winsock.h
中定义,根据微软自己的说法,你可以通过在包含winsock.h
之前定义它来增加它的值:
FD_SETSIZE
是相当愚蠢的事情。2048个并发连接(或更多)已经在epoll_wait
大幅优于select
和poll
的范围内,因为它不需要每次复制8千字节的数据,并且不需要每次遍历两千个描述符。 - Damon