首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么必须在边缘触发epoll函数中使用非阻塞fd?

为什么必须在边缘触发epoll函数中使用非阻塞fd?
EN

Stack Overflow用户
提问于 2013-02-01 17:32:02
回答 3查看 3.4K关注 0票数 6

我在web上阅读了关于边缘触发epoll函数的文档如下:

代码语言:javascript
复制
1. The file descriptor that represents the read side of a pipe (rfd) is registered on the epoll instance.
2. A pipe writer writes 2 kB of data on the write side of the pipe.
3. A call to epoll_wait(2) is done that will return rfd as a ready file descriptor.
4. The pipe reader reads 1 kB of data from rfd.
5. A call to epoll_wait(2) is done.
.......
.......

使用epoll作为边缘触发接口的建议方法如下: i)使用非阻塞文件描述符ii)仅在read(2)或write(2)返回EAGAIN之后为事件调用epoll_wait。

我理解2,但我不知道为什么要使用非阻塞文件描述符。

有人能解释一下为什么使用非阻塞文件描述符吗?为什么可以在级别触发的epoll函数中使用阻塞文件描述符?

EN

回答 3

Stack Overflow用户

发布于 2013-02-01 17:41:54

这个想法是,当您有一个边缘触发的通知,即有数据要拥有时,尝试完全排出文件描述符。因此,一旦epoll()返回,您就会遍历read()write(),直到不再有数据时返回-EAGAIN

如果fd是阻塞打开的,那么最后一个read()write()也会阻塞,您将没有机会返回到epoll()调用来等待整个fd集。当以非阻塞方式打开时,最后一个read()/write()确实会返回,并且您确实有机会返回到轮询。

当以级别触发的方式使用epoll()时,这并不是什么大问题,因为在这种情况下,如果有任何数据需要,epoll()将立即返回。因此,一个(伪代码)循环,例如:

代码语言:javascript
复制
while (1) {
  epoll();
  do_read_write();
}

将会起作用,因为只要有数据,您就可以调用do_read_write()。当使用边缘触发的epoll时,如果新数据出现在完成do_read_write()和下一次调用epoll()之间,则可能会出现新数据可能丢失的通知。

票数 9
EN

Stack Overflow用户

发布于 2013-09-14 04:12:12

我猜这是因为边缘触发的语义。根据语义,只有在接收到EAGAIN之后,边缘触发器才会引发另一个事件。在阻塞套接字的情况下,没有EAGAIN。你可以用其他方式来定义它,但是Linux就是这样定义它的。换句话说,如果您使用阻塞套接字,您不知道什么时候可以安全地调用epoll_wait。

票数 0
EN

Stack Overflow用户

发布于 2017-04-17 18:56:51

您必须读取或写入epoll的ET模式上的所有数据,因为et模式在标志更改后触发一次。读取完所有数据后,如果使用块读取或写入,则线程必须挂起。因此必须使用非阻塞。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14643249

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档