[Linux] Linux网络编程

来源:互联网 发布:手机探测软件 编辑:程序博客网 时间:2024/04/20 21:13

EPoll的两种工作模式

本文主要包含两个方面:

  • Linux中的EAGAIN错误码
  • EPoll的两种工作模式

一、EAGAIN

从字面上来看,表示再试一次的意思,这个错误经常出现在当应用程序进行一些非阻塞操作(对文件或socket)的时候,例如以O_NONBLOCKING的标志打开文件/socket/FIFO,如果连续做read操作而没有数据可读,此时程序不会阻塞起来等待数据准备就绪返回,read函数会返回一个EAGAIN错误,提示你的应用程序现在没有数据可读请稍后再试。

二、EPoll的两种工作模式

我们都知道EPoll有两种工作模式:

  • ET(边沿触发)
  • LT(水平触发)

其中,ET工作模式是高速工作模式,只支持no-block socket,在这种模式下,当描述符从未就绪变为就绪时,内核通过epoll通知,然后它会假设你知道文件描述符已经就绪,并且不再为这个文件描述符发送更多的就绪通知,等到下次有新的数据进来的时候才会再次再次通知你;而LT工作模式是默认的工作模式,并且同时支持block 和no-block socket,在这种工作模式下,内核告诉你一个文件描述符准备就绪了,然后你可以对这个就绪的fd进行IO操作,如果你不进行任何操作,内核还是会继续通知你的。

LT工作模式对代码编写要求比较低,并且不容易出现问题,但是它的问题就是它的效率低于ET工作模式,尤其在大并发、大流量的情况下。

ET工作模式效率非常高,在并发大流量的情况下,会比LT少很多的epoll的系统调用,但是对编程要求高,需要细致的处理每个请求,否则容易出现丢失事件的情况。

那么为什么ET工作模式只能使用非阻塞的socket呢?下面我以EPOLLIN事件为例进行说明:EPOLLIN事件只有当对端有数据写入时才会触发,所以触发一次后需要不断读取所有数据直到读完EAGAIN为止,否则剩下的数据只有在下次对端有写入时才能一起取出来了。并且EPOLLIN事件只有对端有新数据写入时才会触发一次,对于EPOLLIN事件,必须要将该文件描述符一直读到空,让error返回EAGAIN为止。

如果你的文件描述符不是非阻塞的,对于读,由于需要一直读直到把数据读完,所以大家在编写程序的时候一般会用一个循环一直读取socket,那么这个循环势必在最后一次阻塞,即没有数据可读的情况下,阻塞式socket会在据读完之后一直阻塞下去,而非阻塞式的socket则返回<0,并让errno返回EAGAIN。

三、参考链接

  • EPoll的两种模式

  • 使用epoll时需要将socket设为非阻塞吗?

  • epoll的两种模式详解

原创粉丝点击