我在web上阅读了关于边缘触发epoll函数的文档如下:
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函数中使用阻塞文件描述符?
发布于 2013-02-01 17:41:54
这个想法是,当您有一个边缘触发的通知,即有数据要拥有时,尝试完全排出文件描述符。因此,一旦epoll()返回,您就会遍历read()或write(),直到不再有数据时返回-EAGAIN。
如果fd是阻塞打开的,那么最后一个read()或write()也会阻塞,您将没有机会返回到epoll()调用来等待整个fd集。当以非阻塞方式打开时,最后一个read()/write()确实会返回,并且您确实有机会返回到轮询。
当以级别触发的方式使用epoll()时,这并不是什么大问题,因为在这种情况下,如果有任何数据需要,epoll()将立即返回。因此,一个(伪代码)循环,例如:
while (1) {
epoll();
do_read_write();
}将会起作用,因为只要有数据,您就可以调用do_read_write()。当使用边缘触发的epoll时,如果新数据出现在完成do_read_write()和下一次调用epoll()之间,则可能会出现新数据可能丢失的通知。
发布于 2013-09-14 04:12:12
我猜这是因为边缘触发的语义。根据语义,只有在接收到EAGAIN之后,边缘触发器才会引发另一个事件。在阻塞套接字的情况下,没有EAGAIN。你可以用其他方式来定义它,但是Linux就是这样定义它的。换句话说,如果您使用阻塞套接字,您不知道什么时候可以安全地调用epoll_wait。
发布于 2017-04-17 18:56:51
您必须读取或写入epoll的ET模式上的所有数据,因为et模式在标志更改后触发一次。读取完所有数据后,如果使用块读取或写入,则线程必须挂起。因此必须使用非阻塞。
https://stackoverflow.com/questions/14643249
复制相似问题