我是unix programming新手,今天我正在尝试epoll但遇到了问题。
在level-triggered模式下,我认为每个新输入事件(包括Ctrl-D都会导致epoll_wait返回。 工作正常。 但是,当我键入aaa ,请Ctrl-D ,然后read块。 当我键入Ctrl-D ,没有。
你能解释一下会发生什么吗?
当epoll_wait完成并根据fd准备好时,我应该读取所有数据吗?
谢谢!
#include
#include
#include
#include
#include
int main(int argc, const char *argv[]) {
// create event
struct epoll_event stdin_ev, events[10];
// set event
stdin_ev.events = EPOLLIN;
stdin_ev.data.fd = STDIN_FILENO;
// create epoll
int epfd = epoll_create(1), i, rcnt;
char c;
// set monitoring STDIN_FILENO
epoll_ctl(epfd, EPOLL_CTL_ADD, STDIN_FILENO, &stdin_ev);
while(1) {
int ret = epoll_wait(epfd, events, 1, 1000);
// timeout or failed
if(ret == 0) {
fprintf(stdout, "timeout\n");
continue;
} else if (ret < 0) {
perror("ret<0");
exit(EXIT_FAILURE);
}
// readable
fprintf(stdout, "%d event(s) happened...\n", ret);
for(i=0; i < ret; i++) {
if(events[i].data.fd == STDIN_FILENO &&\
events[i].events&EPOLLIN) {
// read a char
rcnt = read(STDIN_FILENO, &c, 1);
// if read 0 char, EOF?
if(rcnt != 1) {
fprintf(stdout, "read %d byte\n", rcnt);
continue;
}
// else print ascii
fprintf(stdout, "ascii code: %d\n", c);
}
}
}
close(epfd);
return 0;
}
输入: aaa + Ctrl-D ,结果:
timeout
aaa //
1 event(s) happened...
ascii code: 97
1 event(s) happened...
ascii code: 97
1 event(s) happened...
ascii code: 97
1 event(s) happened...
^C //
然后,我尝试将STDIN_FILENO设置为非阻塞,并且我发现epoll_wait仍然告诉您有一个可读事件,尽管read()返回-1。 但是,如果我只键入Ctrl-D ,则read()返回0。
#include
#include
#include
#include
#include
int set_nonblock(int sfd) {
int flags, s;
flags = fcntl(sfd, F_GETFL, 0);
if(flags == -1) {
perror("fcntl");
return -1;
}
flags |= O_NONBLOCK;
s = fcntl(sfd, F_SETFL, flags);
if(s == -1) {
perror("fcntl");
return -1;
}
return 0;
}
int main(int argc, const char *argv[]) {
// create event
struct epoll_event stdin_ev, events[10];
// set event
stdin_ev.events = EPOLLIN;
stdin_ev.data.fd = STDIN_FILENO;
// create epoll
int epfd = epoll_create(1), i, rcnt;
char c;
// set nonblocking
if(set_nonblock(STDIN_FILENO) != 0) {
exit(EXIT_FAILURE);
};
// set monitoring STDIN_FILENO
epoll_ctl(epfd, EPOLL_CTL_ADD, STDIN_FILENO, &stdin_ev);
while(1) {
int ret = epoll_wait(epfd, events, 1, 1000);
// timeout or failed
if(ret == 0) {
fprintf(stdout, "timeout\n");
continue;
} else if (ret < 0) {
perror("ret<0");
exit(EXIT_FAILURE);
}
// readable
fprintf(stdout, "%d event(s) happened...\n", ret);
for(i=0;i < ret;i++) {
if(events[i].data.fd == STDIN_FILENO &&\
events[i].events&EPOLLIN) {
// read a char
rcnt = read(STDIN_FILENO, &c, 1);
// if read 0 char, EOF?
if(rcnt != 1) {
fprintf(stdout, "read %d byte\n", rcnt);
continue;
}
// else print ascii
fprintf(stdout, "ascii code: %d\n", c);
}
}
}
close(epfd);
return 0;
}
结果:
timeout
1 event(s) happened... //
read 0 byte // 0
timeout
timeout
aaa // `aaa`+`Ctrl-D`
1 event(s) happened...
ascii code: 97
1 event(s) happened...
ascii code: 97
1 event(s) happened...
ascii code: 97
read -1 byte // `EPOLLIN` still happens.
timeout
^C