选择高于255的文件描述符不会检查该文件描述符是否已打开。这是我的示例代码:
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <sys/select.h>
int main()
{
fd_set set;
for(int i = 5;i<FD_SETSIZE;i++)
{
printf("--> i is %d\n", i);
FD_ZERO(&set);
FD_SET(i, &set);
close(i);
int retval = select(FD_SETSIZE, &set, NULL, NULL, NULL);
if(-1 == retval)
{
perror("select");
}
}
}
这将导致:
--> i is 5
select: Bad file descriptor
...
--> i is 255
select: Bad file descriptor
--> i is 256
然后应用程序阻塞了。
为什么这不会在256到FD_SETSIZE之间创建EBADF
?
来自评论的请求信息:
prlimit
的结果为:
NOFILE max number of open files 1024 1048576
这是运行
strace ./test_select
的结果:select(1024, [127], NULL, NULL, NULL) = -1 EBADF (Bad file descriptor)
dup(2) = 3
fcntl(3, F_GETFL) = 0x8402 (flags O_RDWR|O_APPEND|O_LARGEFILE)
fstat(3, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 2), ...}) = 0
write(3, "select: Bad file descriptor\n", 28select: Bad file descriptor
) = 28
close(3) = 0
write(1, "--> i is 128\n", 13--> i is 128
) = 13
close(128) = -1 EBADF (Bad file descriptor)
select(1024, [128], NULL, NULL, NULL
评论中的疑惑解答:
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <sys/select.h>
#include <fcntl.h>
int main()
{
char filename[80];
int fd;
for(int i = 5;i<500;i++)
{
snprintf(filename, 80, "/tmp/file%d", i);
fd = open(filename, O_RDWR | O_APPEND | O_CREAT);
}
printf("--> fd is %d, FD_SETSIZE is %d\n", fd, FD_SETSIZE);
fd_set set;
FD_ZERO(&set);
FD_SET(fd, &set);
int retval = select(FD_SETSIZE, NULL, &set, NULL, NULL);
if(-1 == retval)
{
perror("select");
}
}
结果是:
$ ./test_select
--> fd is 523, FD_SETSIZE is 1024
进程正常退出,不会阻塞。
EBADF
。此外,您正在使用未初始化的内容进行选择,这非常容易生成EBADF
。 - Antti Haapala -- Слава УкраїніEBADF
?此外,set
在每次循环迭代中都会初始化。 - kuga