条件触发和边缘触发 及 epoll 的优点


  • 条件触发: 只要输入缓冲有数据就会一直通知该事件
  • 边缘触发: 输入缓冲收到数据时仅注册1次该事件,即使输入缓冲中还留有数据,也不会再进行注册
  • 水平触发(level-triggered,也被称为条件触发):只要满足条件,就触发一个事件(只要有数据没有被获取,内核就不断通知你)
  • 边缘触发(edge-triggered): 每当状态变化时,触发一个事件

举个读socket的例子,假定经过长时间的沉默后,现在来了100个字节,这时无论边缘触发和条件触发都会产生一个read ready notification通知应用程序可读。应用程序读了50个字节,然后重新调用api等待io事件。

这时条件触发的api会因为还有50个字节可读从而立即返回用户一个read ready notification。而边缘触发的api因为可读这个状态没有发生变化而陷入长期等待

因此在使用边缘触发的api时,要注意每次都要读到socket返回EWOULDBLOCK为止,否则这个socket就算废了。而使用条件触发的api时,如果应用程序不需要写就不要关注socket可写的事件,否则就会无限次的立即返回一个write ready notification。大家常用的select就是属于条件触发这一类,长期关注socket写事件会出现CPU 100%的毛病。

epoll的优点:

  1. 支持一个进程打开大数目的socket描述符(FD)

select最不能忍受的是一个进程所打开的FD是有一定限制的,由FD_SETSIZE设置,默认值是2048。对于那些需要支持的上万连接数目的IM服务器来说显然太少了。这时候你一是可以选择修改这个宏然后重新编译内核,不过资料也同时指出这样会带来网络效率的下降,二是可以选择多进程的解决方案(传统的 Apache方案),不过虽然linux上面创建进程的代价比较小,但仍旧是不可忽视的,加上进程间数据同步远比不上线程间同步的高效,所以也不是一种完美的方案。不过 epoll则没有这个限制,它所支持的FD上限是最大可以打开文件的数目,这个数字一般远大于2048,举个例子,在1GB内存的机器上大约是10万左右,具体数目可以cat /proc/sys/fs/file-max察看,一般来说这个数目和系统内存关系很大。

  1. IO效率不随FD数目增加而线性下降

传统的select/poll另一个致命弱点就是当你拥有一个很大的socket集合,不过由于网络延时,任一时间只有部分的socket是”活跃”的, 但是select/poll每次调用都会线性扫描全部的集合,导致效率呈现线性下降。但是epoll不存在这个问题,它只会对”活跃”的socket进行 操作—这是因为在内核实现中epoll是根据每个fd上面的callback函数实现的。那么,只有”活跃”的socket才会主动的去调用 callback函数,其他idle状态socket则不会,在这点上,epoll实现了一个”伪”AIO,因为这时候推动力在os内核。在一些 benchmark中,如果所有的socket基本上都是活跃的—比如一个高速LAN环境,epoll并不比select/poll有什么效率,相反,如果过多使用epoll_ctl,效率相比还有稍微的下降。但是一旦使用idle connections模拟WAN环境,epoll的效率就远在select/poll之上了。

  1. 使用mmap加速内核与用户空间的消息传递。

这点实际上涉及到epoll的具体实现了。无论是select,poll还是epoll都需要内核把FD消息通知给用户空间,如何避免不必要的内存拷贝就 很重要,在这点上,epoll是通过内核于用户空间mmap同一块内存实现的。而如果你想我一样从2.5内核就关注epoll的话,一定不会忘记手工 mmap这一步的。

  1. 内核微调

这一点其实不算epoll的优点了,而是整个linux平台的优点。也许你可以怀疑linux平台,但是你无法回避linux平台赋予你微调内核的能力。 比如,内核TCP/IP协议栈使用内存池管理sk_buff结构,那么可以在运行时期动态调整这个内存pool(skb_head_pool)的大小 — 通过echo XXXX>/proc/sys/net/core/hot_list_length完成。再比如listen函数的第2个参数(TCP完成3次握手 的数据包队列长度),也可以根据你平台内存大小动态调整。更甚至在一个数据包数目巨大但同时每个数据包本身大小却很小的特殊系统上尝试最新的NAPI网卡驱动架构。 ?

时间: 2024-08-03 19:29:53

条件触发和边缘触发 及 epoll 的优点的相关文章

实例浅析epoll的水平触发和边缘触发,以及边缘触发为什么要使用非阻塞IO

一.基本概念                                                          我们通俗一点讲: Level_triggered(水平触发):当被监控的文件描述符上有可读写事件发生时,epoll_wait()会通知处理程序去读写.如果这次没有把数据一次性全部读写完(如读写缓冲区太小),那么下次调用 epoll_wait()时,它还会通知你在上没读写完的文件描述符上继续读写,当然如果你一直不去读写,它会一直通知你!!!如果系统中有大量你不需要读写的就

epoll 水平触发和边缘触发的区别

EPOLLLT——水平触发EPOLLET——边缘触发 epoll有EPOLLLT和EPOLLET两种触发模式,LT是默认的模式,ET是“高速”模式.LT模式下,只要这个fd还有数据可读,每次 epoll_wait都会返回它的事件,提醒用户程序去操作,而在ET(边缘触发)模式中,它只会提示一次,直到下次再有数据流入之前都不会再提示了,无 论fd中是否还有数据可读.所以在ET模式下,read一个fd的时候一定要把它的buffer读光,也就是说一直读到read的返回值小于请求值,或者 遇到EAGAIN

epoll的水平触发和边缘触发

水平触发(Level Triggered): 当满足条件时, 触发.  (select和poll采用该方式)边缘触发(Edge Triggered): 当状态变化时,触发.  (信号驱动[Signal-Driven I/O]采用该方式) 过程: 当数据到来的时候, 触发器满足条件,发送通知, 进程接收到通知后,请求内核读取数据. 水平触发,是因为数据就绪,可IO,满足条件,则发送通知. 边缘触发,是因为状态发生了变化, 则发送通知. 理想情况下, 两种触发方式都能满足需求. 但是当内核在读取数据

水平触发和边缘触发的区别

水平触发(level-triggered,也被称为条件触发)LT:  只要满足条件,就触发一个事件(只要有数据没有被获取,内核就不断通知你) 边缘触发(edge-triggered)ET: 每当状态变化时,触发一个事件. "举个读socket的例子,假定经过长时间的沉默后,现在来了100个字节,这时无论边缘触发和条件触发都会产生一个read ready notification通知应用程序可读.应用程序读了50个字节,然后重新调用api等待io事件.这时条件触发的api会因为还有50个字节可读,

IO多路复用的水平触发与边缘触发

在linux的IO多路复用中有水平触发,边缘触发两种模式,这两种模式的区别如下: 水平触发:如果文件描述符已经就绪可以非阻塞的执行IO操作了,此时会触发通知.允许在任意时刻重复检测IO的状态,没有必要每次描述符就绪后尽可能多的执行IO.select,poll就属于水平触发. 边缘触发:如果文件描述符自上次状态改变后有新的IO活动到来,此时会触发通知.在收到一个IO事件通知后要尽可能多的执行IO操作,因为如果在一次通知中没有执行完IO那么就需要等到下一次新的IO活动到来才能获取到就绪的描述符.信号

水平触发与边缘触发

水平触发(Level Triggered,也称条件触发):select()和poll()将就绪的文件描述符告诉进程后,如果进程没有对其进行IO操作,那么下次调用select()和poll()的时候将再次报告这些文件描述符,所以它们一般不会丢失就绪的消息. 边缘触发(Edge Triggered):只告诉进程哪些文件描述符刚刚变为就绪状态,它只说一遍,如果我们没有采取行动,那么它将不会再次告知,这种方式称为边缘触发. ? ? 两者都会带来一系列问题:例如当100字节到达后,应用程序只读取了一部分,

Linux网络编程之select、poll、epoll的比较,以及epoll的水平触发(LT)和边缘触发(ET)

Linux的网络通信先后推出了select.poll.epoll三种模式. select有以下三个问题: (1)每次调用select,都需要把fd集合从用户态拷贝到内核态,这个开销在fd很多时会很大. (2)同时每次调用select都需要在内核遍历传递进来的所有fd,这个开销在fd很多时也很大. (3)select支持的文件描述符数量太小了,默认是1024. poll解决了第三个问题,select保存描述符fd的数据结构是数组,poll改成了链表,突破了fd的个数限制. 但是第1和第2个问题依然

软触发和硬触发的区别

转自: 什么是硬件触发和软件触发 硬件触发:数据采集卡被动等待触发信号,接收到信号后才进行数据采集:触发信号可由某个仪器在一定状态下发出.如有的自动测量系统中的高速数据卡就接收position controller发出的触发信号.而有的则依靠矢量网络分析仪接收外部触发信号.之所以能接收触发信号,和仪器的工作模式有关.硬件触发与数据采集卡有关. 软件触发:通过软件主动查询信号或仪器当前状态,符合条件则控制系统采集信号.软触发有着更大的柔性,但系统整体速度和测量精度一般不如硬触发,特别是有着复杂信号

【安富莱二代示波器教程】第9章 示波器设计—自动触发和普通触发

第9章        示波器设计-自动触发和普通触发 自带触发和普通触发是示波器设计中比较重要的两个功能,本章节为大家讲解二代示波器中自动触发和普通触发的实现. 9.1    自动触发 9.2    普通触发 9.3     总结 9.1  自动触发 由于示波器模拟前端模块稍有些问题,所以自动触发功能是用软件实现的.软件实现自动触发比较容易实现,具体的实现代码如下: /* 通过软件检测实现上升沿触发,并保留最后600的数据不做检测,用于直接显示 2048-600 = 1448; */ j = 0