剖析epoll机制

剖析epoll机制

  • Linux epoll机制;
  • 写这篇文章的原因是, 上次百度面试被问到一个事件怎么添加到epoll的双向链表中的; 这个问题比较深入, 涉及到内核的实现问题, 今天就来理解一下;
  • epoll和select/poll完全不同, epoll通过在Linux内核中申请一个简易的文件系统(文件系统一般用什么实现? B+树);
    • B+树, 相当于一个2-3的扩展, 一个节点可以有多个数据项, B+树而且它的叶子结点才有真正的数据, 并用一个单链表链接起来的;
  • epoll调用分成3个部分:
    • 调用epoll_create()建立一个epoll对象(在epoll文件系统中为这个句柄对象分配资源);
    • 调用epoll_ctl向epoll对象中添加或删除一些套接字;
    • 调用epoll_wait收集发生的事件的连接;
      • epoll_wait的调用非常高, 因为调用epoll_wait时, 并没有向操作系统复制连接的句柄数据, 内核不需要遍历全部的连接;
  • epoll_create会创建一个eventpoll结构体, 这个结构体中有两个成员与epoll的使用方式密切相关;
    • struct rb_root rbr; //红黑树的根节点, 这棵树中存储着所有添加到epoll中的需要监控的事件
    • epoll机制通过红黑树保存需要监控的事件;
    • struct list_head rdlist; // 双链表中存放着将要通过epoll_wait返回给用户的满足条件的活跃事件;
    • epoll机制通过一个双链表来保存活跃的事件;
  • 每一个epoll对象都有一个独立的eventpoll结构体, 用于存放通过epoll_ctl方法向epoll向epoll对象中添加进来的事件;
    • 这些事件都会被挂载在红黑树中, 重复添加的事件就可以通过红黑树而高效的识别出来(红黑树的插入时间效率是lgn, 其中n为树的高度);
    • 而所有添加到epoll中的事件都会与设备(网卡)驱动程序建立回调关系, 也就是说, 当相对应的事件发生时会调用这个回调方法;
    • 这个回调方法在内核中叫ep_poll_callback, 它将发生的事件添加到rdlist双链表中;
  • 在epoll中, 对于每一个事件, 都会建立一个epitem结构体;
    struct epitem{
        struct rb_node  rbn;            //红黑树节点
        struct list_head    rdllink;    //双向链表节点
        struct epoll_filefd  ffd;       //事件句柄信息
        struct eventpoll *ep;           //指向其所属的eventpoll对象
        struct epoll_event event;       //期待发生的事件类型
    }
  • 当调用epoll_wait检查是否有事件发生时, 只需要检查eventpoll对象中的rdlist双向链表中是否有epitem元素即可;

    • 如果红黑树不为空, 则把发生的事件复制到用户态, 同时把事件的数量返回给用户;
    • 双向链表的每个节点都是基于epitem结构中的rdlink成员;
    • 红黑树中的每个节点都是基于eptiem结构体中的rbn成员;
  • 通过红黑树和双向链表数据结构, 并结合回调机制, 照就了epoll的高效;
  • 怎么把事件添加到双向链表中?
    • 在调用epoll_ctl时, 如果增加socket句柄, 则检查在红黑树中是否存在, 如果存在则立即返回, 不存在则添加到树干上, 然后向内核注册回调函数, 回调函数用于当中断事件来临时向准备就绪链表中插入数据;
    • 那意思是中断函数会自动调用回调函数, 然后向准备就绪的双向链表中插入数据, 把就绪的事件加入到双向链表中;
  • nginx的epoll;

原文地址:https://www.cnblogs.com/longjiang-uestc/p/9658007.html

时间: 2024-08-27 04:32:43

剖析epoll机制的相关文章

【Unix环境编程】select、poll、epoll机制的联系与区别

在linux设计并发网络程序,主要有如下几种模型:Apache模型(Process Per Connection, PPC).TPC(Thread Per Connection)模型,select机制.poll机制以及epoll. 1.  PPC/TPC模型 这两种模型思想类似,每一个新的链接就用一个线程或者进程处理.PPC使用使用进程.TPC使用线程.缺点是连接多了以后,这么多进程和线程的切换非常大.因此这类模型的能接受的最大连接数不会太高,一般几百个左右. 2.  select机制 PPC/

高性能网络编程 - epoll机制

select系统调用不仅对描述符的数量有限制,而且在高并发的情况下,哪怕只有一个活跃的套接字,也要轮询全部的fd set,而epoll采用回调的事件通知机制,只需要处理活跃的套接字.比如Nginx服务器采用的就是epoll,下面这个程序(当接收到大于10B的数据时)展示了epoll在边沿触发和电平触发的不同表现,在edge-trigger模式下,需要我们的程序一次将这次的事情处理完成(比如把数据全部读取),因为这个事件下次不会加到内核事件注册表中了,相反level-trigger模式下就跟我们的

linux epoll机制对TCP 客户端和服务端的监听C代码通用框架实现

1 TCP简介 tcp是一种基于流的应用层协议,其"可靠的数据传输"实现的原理就是,"拥塞控制"的滑动窗口机制,该机制包含的算法主要有"慢启动","拥塞避免","快速重传". 2 TCP socket建立和epoll监听实现 数据结构设计 linux环境下,应用层TCP消息体定义如下: typedef struct TcpMsg_s { TcpMsgHeader head; void* msg; }TcpM

嵌入式 Linux网络编程(五)——epoll机制

嵌入式 Linux网络编程(五)--epoll机制 一.epoll简介 epoll是在2.6内核中提出的,是select和poll的增强版本.epoll更加灵活,没有描述符限制,使用一个文件描述符管理多个描述符,将用户关系的文件描述符的事件存放到内核的一个事件表中. 1.epoll函数 #include <sys/epoll.h> int epoll_create(int size); 创建一个epoll的句柄,size表示监听的文件描述的数量 int epoll_ctl(int epfd,

linux下epoll机制实现多用户并发连接

linux下epoll机制我就不再阐述了,网上找了好多资料和例子,发现和我想要的功能完全不一样,所以就自己写了一个. 实现的功能是,有很多客户端同时连接服务器,例如,S为服务器,有客户端A和客户端B要连接服务器,他们都需要验证密码,若A先连接服务器,此时不输入密码:B再连接服务器,此时,B输入密码的话,服务器不会响应,必须等A先验证完,才可以.我给的例子,可以实现:若A连接了服务器而没有输入密码,B再连接,这是服务器可以为B生成一个线程,确认B的密码后,将客户端的client_sockfd加入到

linux下select/poll/epoll机制的比较

select.poll.epoll简介 epoll跟select都能提供多路I/O复用的解决方案.在现在的Linux内核里有都能够支持,其中epoll是Linux所特有,而select则应该是POSIX所规定,一般操作系统均有实现 select: select本质上是通过设置或者检查存放fd标志位的数据结构来进行下一步处理.这样所带来的缺点是: 1. 单个进程可监视的fd数量被限制,即能监听端口的大小有限. 一般来说这个数目和系统内存关系很大,具体数目可以cat /proc/sys/fs/fil

epoll机制:epoll_create、epoll_ctl、epoll_wait、close

在Linux的网络编程中,很长的时间都在使用select来做事件触发.在linux新的内核中,有了一种替换它的机制,就是epoll.相比于select,epoll最大的好处在于它不会随着监听fd数目的增长而降低效率.因为在内核中的select实现中,它是采用轮询来处理的,轮询的fd数目越多,自然耗时越多.并且,linux/posix_types.h头文件有这样的声明:#define__FD_SETSIZE   1024         表示select最多同时监听1024个fd,当然,可以通过修

安卓输入子系统之inotify与epoll机制【学习笔记】【原创】

平台信息:内核:linux3.1.0系统:android5.0平台:tiny4412 作者:庄泽彬(欢迎转载,请注明作者) 说明: 韦老师的安卓视频学习笔记 一.在安卓的输入子系统中如何监听文件的产生以及监听文件是否有数据的输入,文件的监听主要使用的是inotify机制来监听文件的创建以及删除.使用epoll可以用来监听文件是否有数据的变化.下面针对这两种机制分别编程,简单的了解以及如何使用. 二.使用inotify监听文件的创建以及删除. 2.1我们先来看看现象之后在来看看具体的代码是如何实现

epoll机制和简述

在linux的网络编程中,很长的时间都在使用select来做事件触发.在linux新的内核中,有了一种替换它的机制,就是epoll.相比于select,epoll最大的好处在于它不会随着监听fd数目的增长而降低效率.因为在内核中的select实现中,它是采用轮询来处理的,轮询的fd数目越多,自然耗时越多.并且,linux/posix_types.h头文件有这样的声明: #define__FD_SETSIZE 1024 表示select最多同时监听1024个fd,当然,可以通过修改头文件再重编译内