linux中read阻塞原理,c - 为什么在这种情况下read()会阻塞?(Linux epoll) - 堆栈内存溢出...

我是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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值