下面这段代码运行没有问题和我预期的一样,程序运行之后一直阻塞,当我在终端输入内容并回车,则程序退出。但是打开注释的两行则当我在终端输入内容并回车不会退出不知道为何。
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/select.h>
#include <sys/time.h>
int main(void)
{
fd_set read_set;
int fd1, fd2, maxfdp;
struct timeval time_val;
fd1 = open("./test.txt",O_RDONLY);
fd2 = open("./temp.file",O_RDONLY);
maxfdp = fd2 + 1;
FD_ZERO(&read_set);
FD_SET(0, &read_set);
// FD_SET(fd1, &read_set);
// FD_SET(fd2, &read_set);
time_val.tv_sec = 10;
time_val.tv_usec = 0;
while(1)
{
switch(select(maxfdp, &read_set, NULL, NULL, &time_val))
{
case -1:
perror("select error:");
break;
case 0:
printf("no fd prepared\n");
break;
default:
for (int i = 0; i < maxfdp; ++i)
{
if (FD_ISSET(i, &read_set))
{
printf("fd %d in the read_set\n", i);
if (i == STDIN_FILENO)
{
exit(0);
}
}
}
break;
}
sleep(1);
}
return 0;
}
测试结果:
[zhoumengkang@localhost unix]$ gcc select_demo.c -std=c99
[zhoumengkang@localhost unix]$ ./a.out
zmk
fd 0 in the read_set
[zhoumengkang@localhost unix]$ zmk
但是,如果打开注释的两行,则当我在终端输入回车,则不会退出。(下面的zmk
是在终端的输入)
[zhoumengkang@localhost unix]$ gcc select_demo.c -std=c99
[zhoumengkang@localhost unix]$ ./a.out
fd 3 in the read_set
fd 4 in the read_set
zmk
fd 3 in the read_set
fd 4 in the read_set
zmk
fd 3 in the read_set
fd 4 in the read_set
^C
[zhoumengkang@localhost unix]$
只说取消注释之后为什么不会退出。你应该知道那个为什么会退出。select
会重写read_set
中的内容:select
返回之后read_set
中是可读的文件。由于一开始你没有输入东西(或者说你来不及输入东西,文件就可读了)所以read_set
中不会包含0
。而你重新调用select
的时候,并没有重新把0
加进去,所以以后的循环里,是不会判断0
的。
需要注意的是,select
会重写read_set
中的内容,如果你循环select
,下次select
之前是要重写给read_set
添加值的(一般是清空之后重新添加)。
P.S. 如果一个文件“准备好”如果你一直不读(写)的话,它会一直是“准备好”的