轮询在标准input时手动input,但不是input时pipe道,而不是redirect

考虑这个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”的示例input文件:

 stuff to be read 

假设我运行这个程序,给出一些input并closures它:

 ./a.out test Can read Bytes read: 5 Can't read Can't read ... 

所以让我们尝试通过pipe道读取文件的input/redirect到我的程序的stdin

 cat input | ./a.out # Or ./a.out < input Bytes read: 0 Can read Bytes read: 0 Can read ... 

现在,投票立即返回(不等待超时运行),并给出了我没有预料到的结果。 我知道poll()不正确的文件工作,但如果我没有记错,我不是从文件中读取。

问题是, poll (就像select )只告诉你,例如read的呼吁不会阻止。 它并没有告诉你是否有任何可读的东西。

如果你阅读手册页,你将会看到当它返回0 ,表示文件结束 (或者连接关闭了)。

什么poll是告诉你的是, read可以不被阻塞调用,什么read告诉你通过返回0是没有什么更多的阅读。

通过按下文件结束快捷键(对于Linux系统,在POSIX系统上默认使用Ctrl-D ),可以得到类似的“误报”,用于非管道或重定向的输入示例。