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

标签 linux socket.io nonblocking epoll

我在网上阅读了文档abount edge triggered epoll function如下:

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用作边缘触发(EPOLLET)接口(interface)的建议方式如下: i) 使用非阻塞文件描述符 ii) 仅在 read(2) 或 write(2) 返回 EAGAIN 后才为事件调用 epoll_wait。

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

谁能解释一下使用非阻塞文件描述符的原因? 为什么在level触发的epoll函数中使用阻塞文件描述符就可以了?

最佳答案

这个想法是当你有一个边缘触发的通知有数据要获取时,尝试完全耗尽文件描述符。因此,一旦 epoll() 返回,您将遍历 read()write() 直到它返回 -EAGAIN当没有更多数据时。

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

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

while (1) {
  epoll();
  do_read_write();
}

会起作用,因为只要有数据,您就可以保证调用 do_read_write()。使用边沿触发的 epoll 时,如果新数据出现在 do_read_write() 结束和下一次调用 epoll( )

关于linux - 为什么必须在边缘触发的 epoll 函数中使用非阻塞 fd?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14643249/

相关文章:

linux - 当我在 Linux 中的项目目录上运行 make 命令时,出现以下错误

select - 从 Go channel 获取值(value)

Java:如何在不阻塞的情况下在 InputStream 上测试 EOF?

c - 如何打印void * ioremap_nocache()的返回值?

linux - 使用 linux csh 脚本在许多子目录中执行 makefile

javascript - 在 Angular 应用程序中监听 socket.io

node.js - Socket.IO故障检测

asynchronous - 如何使用 RxJava 发出多个 API 请求并将它们组合起来?

linux - linux内核中spinlock_t的定义

node.js - WebRTC在不同网络中没有视频