我写了一个小测试程序来弄清楚如何与poll
交谈。我创建了三个文件testa
,testb
,testc
并将字符串hello\n
写入第一个文件。所以,这是我对poll
:
poll(polls.data(),polls.size(),-1)
根据联机帮助页,-1
的超时应表明系统调用永远不会超时。但是,它不停地返回而没有任何东西可读。我总是消耗输入的一个字节,可以看到正在打印的hello\n
,但民意调查并没有就此止步。它只是一直假装有东西要读。
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/fcntl.h>
#include <sys/poll.h>
#include <unistd.h>
#include <errno.h>
#include <vector>
#include <map>
#include <string>
#include <iostream>
typedef int fd_t;
int main() {
fd_t const a = open("testa",O_RDONLY);
fd_t const b = open("testb",O_WRONLY);
fd_t const c = open("testc",O_RDWR);
std::map<fd_t,std::string> names{{{a,"testa"},{b,"testb"},{c,"testc"}}};
std::vector<pollfd> polls;
polls.push_back(pollfd{a, POLLIN, 0});
polls.push_back(pollfd{b, 0, 0});
polls.push_back(pollfd{c, POLLIN, 0});
while (poll(polls.data(),polls.size(),-1)) {
for (auto p : polls) {
if ((p.revents & (POLLIN|POLLERR)) == POLLIN) {
std::cout << "{" << p.fd << ", " << p.events << ", " << p.revents << "} ";
char byte;
auto const rr = read(p.fd,&byte,1);
auto const en = errno;
if (rr) {
std::cout << "File " << names[p.fd] << " says something: '" << ((int)byte) << " (" << (((' '<byte) && (byte<127))?byte:'\0') << ")" << "' \n";
} else {
std::cout << "Strange (file " << names[p.fd] << "). errno says " << en << "\n";
}
}
}
}
}
我得到的是:
{3, 1, 1} File testa says something: '104 (h)'
{5, 1, 1} Strange (file testc). errno says 0
{3, 1, 1} File testa says something: '101 (e)'
{5, 1, 1} Strange (file testc). errno says 0
{3, 1, 1} File testa says something: '108 (l)'
{5, 1, 1} Strange (file testc). errno says 0
{3, 1, 1} File testa says something: '108 (l)'
{5, 1, 1} Strange (file testc). errno says 0
{3, 1, 1} File testa says something: '111 (o)'
{5, 1, 1} Strange (file testc). errno says 0
{3, 1, 1} File testa says something: '10 ()'
{5, 1, 1} Strange (file testc). errno says 0
{3, 1, 1} Strange (file testa). errno says 0
{5, 1, 1} Strange (file testc). errno says 0
{3, 1, 1} Strange (file testa). errno says 0
{5, 1, 1} Strange (file testc). errno says 0
{3, 1, 1} Strange (file testa). errno says 0
{5, 1, 1} Strange (file testc). errno says 0
{3, 1, 1} Strange (file testa). errno says 0
{5, 1, 1} Strange (file testc). errno says 0
(永远重复最后两行)
我在3.10-2-amd64内核上使用g++ -Wall -Wextra -std=c++11 poll.cpp -o poll
构建。
答案 0 :(得分:6)
常规文件中的EOF条件仍然可读。换句话说,您的read()
不会阻止。以下是poll()
的不同实现如何在不同类型的文件描述符中对EOF做出反应的清单:http://www.greenend.org.uk/rjk/tech/poll.html
请注意,常规文件始终返回POLLIN。所以你需要单独测试EOF。实际上,对常规文件进行轮询并不会对您有任何影响。你需要套接字或管道或其他东西来测试你的代码。
其他说明:您可能希望在.revents
中查看其他结果。 POLLERR,POLLHUP和POLLNVAL都表示不同的错误情况,需要特殊处理。
答案 1 :(得分:3)
一旦到达文件末尾,它仍然可读,以便poll
立即返回,并且调用read
将立即返回零。您需要处理这种情况,可能是通过关闭它并将其从您当前正在打印Strange
的民意调查中删除。
答案 2 :(得分:2)
本地文件描述符总是准备好执行I / O(与套接字不同,因为它们依赖于I / O的内核内部缓冲区))。在你的情况下,文件描述符总是可以读取,即使它们实际上是空的。