原文: http://weibo.com/p/1001603862394207076573?sudaref=weibo.com
epoll的I/O事件触发方式有两种模式:ET(Edge Triggered)和LT(Level Triggered)。
这个触发模式其实是events(事件)的属性,该属性是和POLLIN、POLLOUT等属性并列且混杂使用的,而events有时依附在fd(文件描述符)上的,所以可以说:这个触发模式是events所依附的fd的属性。区分events和fd的原因是kernel内部实现也是这么区分的:events由eppoll_entry代表,fd由epitem代表。
先简单了解下这两种模式。
LT模式就是针对一个上报事件,如果没处理完,那么下次该事件还在,可以继续处理。而相同场景下的ET模式处理是:下次该事件就不在了,也就是说只通知一次,不给第二次处理的机会。epoll的默认模式是LT,毕竟select/poll都仅仅支持LT模式。
先看ET模式。
ET模式的基本说明:
An application that employs the EPOLLET flag should use nonblocking file descriptors to avoid having a blocking read or write starve a task that is handling multiple file descriptors. The suggested way to use epoll as an edge-triggered (EPOLLET) interface is as follows:
1)with nonblocking file descriptors; and
2)by waiting for an event only after read(2) or write(2) return EAGAIN.
By contrast, when used as a level-triggered interface (the default, when EPOLLET is not specified), epoll is simply a faster poll(2), and can be used wherever the latter is used since it shares the same semantics.
可见,ET模式时要使用非堵塞的fd,并且要采用穷极方式来处理事件(直到得到满意的EAGAIN返回值)。我们再仔细看看处理事件的流程:
Q:Do I need to continuously read/write a file descriptor until EAGAIN when using the EPOLLET flag (edge-triggered behavior) ?
A:Receiving an event from epoll_wait(2) should suggest to you that such file descriptor is ready for the requested I/O operation. You must consider it ready until the next (nonblocking) read/write yields EAGAIN. When and how you will use the file descriptor is entirely up to you.
For packet/token-oriented files (e.g., datagram socket, terminal in canonical mode), the only way to detect the end of the read/write I/O space is to continue to read/write until EAGAIN.
For stream-oriented files (e.g., pipe, FIFO, stream socket), the condition that the read/write I/O space is exhausted can also be detected by checking the amount of data read from / written to the target file descriptor. For example, if you call read(2) by asking to read a certain amount of data and read(2) returns a lower number of bytes, you can be sure of having exhausted the read I/O space for the file descriptor. The same is true when writing using write(2). (Avoid this latter technique if you can‐not guarantee that the monitored file descriptor always refers to a stream-oriented file.)
也就是说,判断结束的方法有两种:看EAGAIN返回值;比较期望count和真实count。
对于ET模式,需要注意的一点是:在eventpoll(标识一个epoll实例)的就绪队列里,放的是events所依附的fd,而不是events本身。这会导致一种捎带现象:一个POLLIN事件触发一次后,不再出现了,虽然用户没有处理完。但是一个新的POLLOUT事件来了,此时旧的POLLIN事件又捎带出来了。(打个比方,人是fd,新帐旧帐是不同的events,则类似于:有旧账没关系,不碰面就行。就怕有新帐,有了新帐,就得碰面并且新帐旧账一起算。。。)
我们觉得,ET模式还是很合理的,跟网卡的NAPI读包方式很像,都带有poll(高效:对于epoll而言,毕竟节省了很多额外的epoll系统调用的次数)特色。。。
再看LT模式。
为何是先看ET再看LT?因为从代码实现上看,我们觉得epoll应该是在支持ET之后才增加的支持LT。
对LT的支持很简单,仅需要在已有ET实现的基础上多几行代码:
在处理上报事件之后又重新将事件放回到eventpoll(标识一个epoll实例)的就绪队列里,也就是说直接给了这些事件(实际上是epitem,即事件所依附的文件描述符)第二次处理的机会(ET模式是没有这个机会的),虽然这个机会可能不需要:因为用户可能第一次就穷极处理完了该事件。可见,LT模式的处理有点低效(特别是在fd数量很大的情况下)。
综上,epoll实现了一种I/O事件的通知方式的两种模式:LT和ET,从效率上看,ET应该更有优势。
[转载] 理解 epoll 的事件触发机制的更多相关文章
-
【深入浅出Linux网络编程】 “基础 -- 事件触发机制”
回顾一下“"开篇 -- 知其然,知其所以然"”中的两段代码,第一段虽然只使用1个线程但却也只能处理一个socket,第二段虽然能处理成百上千个socket但却需要创建同等数量的线程 ...
-
C#事件触发机制
C#的事件触发机制,类似于c++的回调函数机制 我先简单说一下,委托和事件的实质,后期再重开一篇博文来详细说 委托:指向方法的指针,类似于C的函数指针 事件:是一个可以存放0个或多个方法指针的数据结构 ...
-
EventEmitter:nodeJs事件触发机制
Node.js 所有的异步 I/O 操作在完成时都会发送一个事件到事件队列 Node.js 里面的许多对象都会分发事件:一个 net.Server 对象会在每次有新连接时触发一个事件, 一个 fs.r ...
-
html元素双击事件触发机制猜想及疑惑
今天有个同事遇到一个奇怪的问题,我照着他的代码做了一些简化写了这个demo <!DOCTYPE html> <html> <head> <style type ...
-
WinForm中的事件触发机制学习
在一个Form窗体中拖个按钮,双击后系统自动生成代码: private void button1_Click(object sender, EventArgs e) { } 同时在窗体的Initial ...
-
Yii中事件触发机制
控制器初始化中添加事件处理方法,在需要触发的地方直接触发 public function init() { parent::init(); // TODO: Change the autogenera ...
-
python 模拟事件触发机制
EventManager.py # -*- encoding: UTF-8 -*- # 系统模块 from queue import Queue, Empty from threading impor ...
-
[转]as3事件流机制彻底理解
题记: 看过网上一些as3事件流的教程,觉得大多都讲得不甚清楚,让人不能直观的理解事件流.而这篇教程以将事件流过程比喻成捕鱼过程,形象简单. 在此基础上对于as3事件流总算有了全面的理解.事件流机制说 ...
-
android的事件分发机制理解
android的事件分发机制理解 1.事件触发主要涉及到哪些层面的哪些函数(个人理解的顺序,可能在某一层会一次回调其它函数) activity中的dispatchTouchEvent .layout中 ...
随机推荐
-
C# 委托Delegate(一) 基础介绍&;用法
本文是根据书本&网络 前人总结的. 1. 前言 定义&介绍: 委托Delegate是一个类,定义了方法的类型, 使得可以将方法当做另一个方法的参数来进行传递,这种将方法动态地赋给参数的 ...
-
[Android下载]北京新版小学英语三年级上册点读手机软件
小学英语三年级上册点读软件.根据2014年北京教改版教材编写,发音标准.实现点读功能.点到哪里读到哪里.哪里不会点哪里!北京教育科学研究院编写,北京出版社出版.ISBN:9787200108781 ...
-
Linux启动报错missing operating system
用UltraISO制作了一个Red Hat Enterprise Linux Server release 5.7系统的U盘启动盘,然后在一台PC上安装,由于安装过程中在干别的事情,有些选项没有细看. ...
-
关于工程结合git的配置
我们通常把代码放到git sever中,(scm manager)中,上传,下载代码, 可是通常工程的代码改动会有图标提示,改动过的,或者新增的,那么需要在eclipse的工程中做一下简单配置 1,工 ...
-
JDBC——架构层、驱动
JDBC(java Datebase Connector) jdbc驱动程序 四种类型: jdbc-odbc桥接驱动程序 Native-API JDBC-Net Native-Protocol (常见 ...
-
Winform通用模块之流水号生成
打算接下来的时间里把自己觉得用起来还比较好用的通用模块,在这里向大家介绍一下,如果你有更好的想法时,也希望你不吝指点. 1.数据库表及存储过程 在介绍这个通用流水号生成的模块前,我们先来看一下其相关的 ...
-
iOS开发frame, contentSize, contentOffset, contentInset 区别联系浅析
1. 概述 iOS开发中,必然会涉及到布局相关问题,frame,bounds,contenSize,contentOffset,contentInset这几个布局相关概念让许多初学者感到困惑.虽然初步 ...
-
HAUT 1261地狱飞龙 自适应辛普森 数值积分
1261: 地狱飞龙 时间限制: 1 秒 内存限制: 64 MB 提交: 300 解决: 68 题目描述 最近clover迷上了皇室战争,他抽到了一种地狱飞龙,很开心.假设地域飞龙会对距离为d的敌 ...
-
Linux第四节 组管理、用户管理、权限管理 / chmod /chown / umask / vim
三期第三讲1.组管理/用户管理(重要文件系统会实时备份 file-) vim/etc/group: 组管理文件://组名:密码控位键:组id:成员 vim/etc/gshadow:组密码管理文件:// ...
-
Linux下进程间通信的六种机制详解
linux下进程间通信的几种主要手段: 1.管道(Pipe)及有名管道(named pipe):管道可用于具有亲缘关系进程间的通信,有名管道克服了管道没有名字的限制,因此,除具有管道所具 ...