考虑这个C程序:
#include <poll.h>
#include <stdio.h>
#include <unistd.h>
#define TIMEOUT 500 // 0.5 s
#define BUF_SIZE 512
int fd_can_read(int fd, int timeout) {
struct pollfd pfd;
pfd.fd = fd;
pfd.events = POLLIN;
if (poll(&pfd, 1, timeout)) {
if (pfd.revents & POLLIN) {
return 1;
}
}
return 0;
}
int main(int argv, char **argc) {
int fd;
size_t bytes_read;
char buffer[BUF_SIZE];
fd = STDIN_FILENO;
while (1) {
if (fd_can_read(fd, TIMEOUT)) {
printf("Can read\n");
bytes_read = read(fd, buffer, sizeof(buffer));
printf("Bytes read: %zu\n", bytes_read);
}
else {
printf("Can't read\n");
}
}
}
它尝试轮询给定的文件描述符(在这种情况下是stdin的fd),并尝试在可用于读取时读取它。这是一个名为“input”的示例输入文件:
stuff to be read
所以,让我说我运行程序,提供一些输入并关闭它:
./a.out
test
Can read
Bytes read: 5
Can't read
Can't read
...
因此,让我们尝试通过将其内容管道/重定向到我的程序的stdin
来读取文件中的输入:
cat input | ./a.out # Or ./a.out < input
Bytes read: 0
Can read
Bytes read: 0
Can read
...
现在,轮询立即返回(不等待超时用完),并给出我没想到的结果。我知道poll()
无法正确处理文件,但如果我没弄错,我就不会从文件中读取文件。
答案 0 :(得分:8)
问题在于poll
(就像select
)只会告诉您对... read
不会阻止。它没有告诉你是否有任何东西可以阅读。
如果您阅读the read
manual page,您会看到当它返回0
时,它意味着文件结尾(或者套接字连接已关闭)。
poll
告诉您的是,read
可以不受阻挡地调用,read
通过返回0
告诉您的是,没有其他内容可供阅读。
你会得到一个类似的假阳性&#34;通过按下非管道或重定向输入示例的文件结尾快捷键(默认情况下,在Linux上的POSIX系统上 Ctrl-D )。