(转)彻底学会使用epoll(一)——ET模式实现分析
注:之前写过两篇关于epoll实现的文章,但是感觉懂得了实现原理并不一定会使用,所以又决定写这一系列文章,希望能够对epoll有比较清楚的认识。是请大家转载务必注明出处,算是对我劳动成果的一点点尊重吧。另外,文中如果有不全面或者不正确的地方还请大家指出。也可以私信或者发邮件:lvyilong316@163.com
1. ET模式实现分析
1.1 ET和LT的实现区别
首先给出下面一张图,这张图是从我之前的一篇博文——epoll实现分析中摘取并细化的。这张图对理解ET模式已经epoll的工作过程只管重要,当然我自己总结出来后也感觉有的小成就,在这里与大家分享。

注:上图的poll不要理解成和select相似那个poll,这是通过epoll_ctl调用的。
下面简要分析一下epoll的工作过程:
(1) epoll_wait调用ep_poll,当rdlist为空(无就绪fd)时挂起当前进程,知道rdlist不空时进程才被唤醒。
(2) 文件fd状态改变(buffer由不可读变为可读或由不可写变为可写),导致相应fd上的回调函数ep_poll_callback()被调用。
(3) ep_poll_callback将相应fd对应epitem加入rdlist,导致rdlist不空,进程被唤醒,epoll_wait得以继续执行。
(4) ep_events_transfer函数将rdlist中的epitem拷贝到txlist中,并将rdlist清空。
(5) ep_send_events函数(很关键),它扫描txlist中的每个epitem,调用其关联fd对用的poll方法(图中蓝线)。此时对poll的调用仅仅是取得fd上较新的events(防止之前events被更新),之后将取得的events和相应的fd发送到用户空间(封装在struct epoll_event,从epoll_wait返回)。之后如果这个epitem对应的fd是LT模式监听且取得的events是用户所关心的,则将其重新加入回rdlist(图中蓝线),否则(ET模式)不在加入rdlist。
具体代码:
/* 扫描整个txlist链表... */
for (eventcnt = 0, uevent = esed->events;
!list_empty(head) && eventcnt < esed->maxevents;) {
/* 取出第一个成员 */
epi = list_first_entry(head, struct epitem, rdllink);
/* 然后从链表里面移除 */
list_del_init(&epi->rdllink);
/* 读取events,
* 注意events我们ep_poll_callback()里面已经取过一次了, 为啥还要再取?
* 1. 我们当然希望能拿到此刻的最新数据, events是会变的~
* 2. 不是所有的poll实现, 都通过等待队列传递了events, 有可能某些驱动压根没传
* 必须主动去读取. */
revents = epi->ffd.file->f_op->poll(epi->ffd.file, NULL) &
epi->event.events;
if (revents) {
/* 将当前的事件和用户传入的数据都copy给用户空间,
* 就是epoll_wait()后应用程序能读到的那一堆数据. */
if (__put_user(revents, &uevent->events) ||
__put_user(epi->event.data, &uevent->data)) {
/* 如果copy过程中发生错误, 会中断链表的扫描,
* 并把当前发生错误的epitem重新插入到ready list.
* 剩下的没处理的epitem也不会丢弃, 在ep_scan_ready_list()
* 中它们也会被重新插入到ready list */
list_add(&epi->rdllink, head);
return eventcnt ? eventcnt : -EFAULT;
}
eventcnt++;
uevent++;
if (epi->event.events & EPOLLONESHOT)
epi->event.events &= EP_PRIVATE_BITS;
else if (!(epi->event.events & EPOLLET)) {
/*
* If this file has been added with Level
* Trigger mode, we need to insert back inside
* the ready list, so that the next call to
* epoll_wait() will check again the events
* availability. At this point, noone can insert
* into ep->rdllist besides us. The epoll_ctl()
* callers are locked out by
* ep_scan_ready_list() holding "mtx" and the
* poll callback will queue them in ep->ovflist.
*/
/* 嘿嘿, EPOLLET和非ET的区别就在这一步之差呀~
* 如果是ET, epitem是不会再进入到readly list,
* 除非fd再次发生了状态改变, ep_poll_callback被调用.
* 如果是非ET, 不管你还有没有有效的事件或者数据,
* 都会被重新插入到ready list, 再下一次epoll_wait
* 时, 会立即返回, 并通知给用户空间. 当然如果这个
* 被监听的fds确实没事件也没数据了, epoll_wait会返回一个0,
* 空转一次.
*/
list_add_tail(&epi->rdllink, &ep->rdllist);
}
}
}
说明:
l epoll_wait返回的条件是rdlist不空,而使rdlist不空的途径有两个,分别对应图中的红线和蓝线。
l ET和LT模式下的epitem都可以通过红线方式加入rdlist从而唤醒epoll_wait,但LT模式下的epitem还可以通过蓝线方式重新加入rdlist唤醒epoll_wait。所以ET模式下,fd就绪(通过红线加入rdlist)只会被通知一次,而LT模式下只要满足相应读写条件就返回就绪(通过蓝线加入rdlist)。
l ET事件发生仅通知一次的原因是只被添加到rdlist中一次,而LT可以有多次添加的机会。
1.2 两种加入rdlist途径的不同
下面我们来分析一下图中两种将epitem加入rdlist方式(也就是红线和蓝线)的区别。
l 红线:fd状态改变是才会触发。那么什么情况会导致fd状态的改变呢?
对于读取操作:
(1) 当buffer由不可读状态变为可读的时候,即由空变为不空的时候。
(2) 当有新数据到达时,即buffer中的待读内容变多的时候。
对于写操作:
(1) 当buffer由不可写变为可写的时候,即由满状态变为不满状态的时候。
(2) 当有旧数据被发送走时,即buffer中待写的内容变少得时候。
l 蓝线:fd的events中有相应的时间(位置1)即会触发。那么什么情况下会改变events的相应位呢?
对于读操作:
(1) buffer中有数据可读的时候,即buffer不空的时候fd的events的可读为就置1。
对于写操作:
(1) buffer中有空间可写的时候,即buffer不满的时候fd的events的可写位就置1。
说明:红线是时间驱动被动触发,蓝线是函数查询主动触发。
原文:http://blog.chinaunix.net/xmlrpc.php?r=blog/article&uid=28541347&id=4273856
(转)彻底学会使用epoll(一)——ET模式实现分析的更多相关文章
- linux下select,poll,epoll的使用与重点分析
好久没用I/O复用了,感觉差点儿相同都快忘完了.记得当初刚学I/O复用的时候花了好多时间.可是因为那会不太爱写博客,导致花非常多时间搞明确的东西,依旧非常easy忘记.俗话说眼过千遍不如手过一遍,的确 ...
- 三种工厂模式的分析以及C++实现
三种工厂模式的分析以及C++实现 以下是我自己学习设计模式的思考总结. 简单工厂模式 简单工厂模式是工厂模式中最简单的一种,他可以用比较简单的方式隐藏创建对象的细节,一般只需要告诉工厂类所需要的类型, ...
- 基于Java 生产者消费者模式(详细分析)
Java 生产者消费者模式详细分析 本文目录:1.等待.唤醒机制的原理2.Lock和Condition3.单生产者单消费者模式4.使用Lock和Condition实现单生产单消费模式5.多生产多消费模 ...
- 微软和Google的盈利模式对比分析
一: 微软和Google是世界上最成功科技巨头之一,但他们之间却有着不同的产品和业务,二者的盈利方式也各有不同,本文将分析和探讨的二者盈利模式的异同. 微软的盈利模式 在1975年由大学肄业的Bill ...
- Libreswan软件的密钥协商协议IKEv1主模式实现分析
Libreswan软件的密钥协商协议IKEv1主模式实现分析 1 协商过程 IKEv1(互联网密钥交换协议第一版)是IPsec VPN隧道协商使用的标准密钥协商协议,其协商过程如下图所示. 总共来回交 ...
- C2B电商三种主要模式的分析_数据分析师
C2B电商三种主要模式的分析_数据分析师 在过去的一年中电商领域血雨腥风,尤其是天猫.京东.苏宁.当当.易讯等B2C电商打得不亦乐乎.而随着B2C领域竞争进入白热化阶段,C2B模式也在天猫" ...
- epoll ET模式陷阱分析
0. 前言 这篇文章主要记录在使用epoll实现NIO接入时所遇到的问题. 1. epoll简介 epoll是Linux下提供的NIO,其主要有两种模式,ET(Edge trige)和LT(Level ...
- epoll的LT模式缺点
本文为原创,转载请注明:http://www.cnblogs.com/gistao/ epoll提供了ET和LT两种模式,网上文章很多,这里只总结下LT模式下的两个缺点 epoll对fd的管理实现是用 ...
- Linux 网络编程->epoll<-LT/ET模式整理(~相逢何必曾相识~)
今天自己整理一下epoll,网上有很多经典的介绍,看了很多~收藏了很多~还是整理一下做个积累, 自己的东西好找~ 1. epoll 模型简介 epoll 是Linux I/O 多路复用接口 selec ...
随机推荐
- spring 整合freemarker 实现模板继承
<!--freemarker 配置--> <bean id="freemarkerConfig" class="org.springframework. ...
- smartctl----硬盘状态监控
smartmontools介绍 smartmontools是一款开源的磁盘控制,监视工具,可以运行在Linux,Unix,BSD,Solaris,Mac OS,OS/2,Cygwin和Windows上 ...
- 鸟书shell 学习笔记(二) shell中正則表達式相关
通配符与正則表達式的差别 通配符是bash原生支持的语法,正則表達式是处理字符串的一种表示方式, 正則表達式须要支持的工具支持才干够 语系设置 : export LANG=C grep alias 设 ...
- nyoj19(排列组合next_permutation(s.begin(),s.end()))
题目意思: 从n个数中选择m个数,按字典序输出其排列. pid=19">http://acm.nyist.net/JudgeOnline/problem.php?pid=19 例: 输 ...
- Unity3D - 图形性能优化:优化着色器载入时间
Unity官方文档之"图形性能优化-优化着色器载入时间"的翻译,E文链接. Optimizing Shader Load Time 优化着色器载入时间 Shaders are sm ...
- Android新手入门2016(8)--ListView之ArrayAdapter
本文来自肥宝传说之路,引用必须注明出处! ListView是Android中经常使用的控件. 什么是列表视图,让我们先看看图: watermark/2/text/aHR0cDovL2Jsb2cuY3N ...
- 0x26 广搜变形
电路维修 这道题虽然乍一看就会想斜对角的两点之间边权受初始电路的影响要么为0要么为1,但是有一个思考点就是可以通过奇偶性,证明相邻的两个点是不可能在同一个电路中.练习一下双端队列. #include& ...
- netty可靠性
Netty的可靠性 首先,我们要从Netty的主要用途来分析它的可靠性,Netty目前的主流用法有三种: 1) 构建RPC调用的基础通信组件,提供跨节点的远程服务调用能力: 2) NIO通信框架,用于 ...
- Windows下Word.exe在哪?
在这里: C:\Program Files\Microsoft Office\root\Office16
- java代码实现python2中aes加密经历
背景: 因项目需要,需要将一个python2编写的aes加密方式改为java实现. 1.源python2实现 from Crypto.Cipher import AES from binascii i ...