linux select()系统调用如何监视两个文件(文件描述符)以及如何使用计时器参数
我需要使用select系统调用,在这里我必须打开两个文件描述符并对准备好的文件执行读取操作,我需要在每5毫秒后使用一些超时并读取这些文件 以下是我的示例代码:linux select()系统调用如何监视两个文件(文件描述符)以及如何使用计时器参数,c,linux,C,Linux,我需要使用select系统调用,在这里我必须打开两个文件描述符并对准备好的文件执行读取操作,我需要在每5毫秒后使用一些超时并读取这些文件 以下是我的示例代码: int main() { fd_set readfds,writefds; ssize_t nbytes,bytes_read; char buf[20]; int fd_1,fd_2,retval; struct timeval tv; fd_1 = open("test1.txt",
int main()
{
fd_set readfds,writefds;
ssize_t nbytes,bytes_read;
char buf[20];
int fd_1,fd_2,retval;
struct timeval tv;
fd_1 = open("test1.txt", O_RDWR);
if(fd_1 < 0) {
printf("Cannot open file...\n");
return 0;
}
fd_2 = open("test2.txt", O_RDWR);
if(fd_2 < 0) {
printf("Cannot open file_2...\n");
return 0;
}
/* Wait up to five seconds. */
tv.tv_sec = 5;
tv.tv_usec = 0;
for(;;)
{
retval = select(FD_SETSIZE, &readfds, &writefds, NULL, &tv);
printf("select");
perror("select");
exit(EXIT_FAILURE);
//}
for(int i=0; i < FD_SETSIZE; i++)
{
FD_ZERO(&readfds);
if (FD_ISSET(i, &readfds))
{
// read call happens here //
nbytes = sizeof(buf);
bytes_read = read(i, buf, nbytes);
printf("%ld", bytes_read);
}
else
{
perror("read");
exit(EXIT_FAILURE);
}
}
}
在调用select之前,需要初始化文件描述符集。使用当前代码,select以EBADF结束 像这样的东西应该可以做到:
FD_ZERO (&writefds);
for(;;)
{
FD_ZERO (&readfds);
FD_SET(fd_1, &readfds);
FD_SET(fd_2, &readfds);
retval = select(FD_SETSIZE, &readfds, &writefds, NULL, &tv);
if (retval < 0) {
perror("select");
exit(EXIT_FAILURE);
}
for(int i=0; i<FD_SETSIZE; i++)
{
if (FD_ISSET(i, &readfds))
{
// read call happens here //
printf("reading from file: %d\n", i);
nbytes = sizeof(buf);
bytes_read = read(i, buf, nbytes);
printf("read %ld bytes\n", bytes_read);
}
}
}
你也可以检查一下;;循环并仅在出现错误时退出。一旦select行为正常,就可以在第二个for循环内继续调试。这里似乎不使用writefds,所以您也可以在select中将其设置为NULL
还有一个注意事项:由于读取集中只有两个文件,您只需检查FD_ISSETfd_1/FD_ISSETfd_2,而不是迭代所有FD_SETSIZE条目。请,以您的示例代码为例,我尝试了这种方法,但我无法通过这些文件描述符来选择系统调用stuck@rupsum_1998我不太明白。你说你不能通过这些考试是什么意思?具体发生了什么?例如,如果有两个文件描述符,fd_1表示一个文本文件,fd_2表示另一个文本文件,因此select系统调用应该找到哪个进程已准备就绪,并对该文件执行读取操作。这是我无法执行的操作。@rupsum1998。但首先需要在readfds集合中添加这两个文件描述符,如上面的代码示例所示。然后检查select的返回值,如果成功,则进入第二个循环并检查哪些FD已准备好读取。但也不要在检查之前用FD_ZERO擦除您的ReadFD…我尝试了您所说的将FD_1和FD_2添加到readfds的方式,但仍然没有区别。请按照您所说的方式编写代码,如果可能的话,发布示例代码,这将有助于我的理解。