Linux epoll简单脉络

来源:互联网 发布:质量好的挎包淘宝店 编辑:程序博客网 时间:2024/05/01 01:51

Linux I/O多路复用:

  • select
  • poll
  • epoll

select/poll 缺点:

  • 每次查询的时候都要将fd set从用户空间拷贝到内核空间
  • 每次select/poll时都会对fd set中所有的fd进行轮询,在fd set很大但是活跃的fd数量很少时,会大幅降低性能
  • 监控的fd数量有限

epoll的基本实现原理:

  • 三大接口:
    • int epoll_create(int size);//创建一个epoll的句柄,size用来告诉内核这个监听的数目一共有多大
    • int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
    • int epoll_wait(int epfd, struct epoll_event * events, int maxevents, int timeout);
  • 数据结构
    (图片来源:http://blog.csdn.net/tianmohust/article/details/6743987)
    这里写图片描述
  • 工作原理:
    1. epoll_create: 在eventpollfs(epoll模块自建)中创建文件并返回该文件fd(epollfd),创建对应struct file与eventpoll并初始化。
    2. epoll_ctl: 主要是针对ADD操作,就是为要监控的fd创建对应的epitem结构,然后插入到rbr指向的红黑树中(不可以重复插入),然后最关键的是调用poll系统调用,为fd指向的文件,I/O设备或者socket(Linux 一切皆是文件)注册回调函数,这样在fd对应的文件发生状态变化时,就会调用callback, 执行一些指定的操作,比如说将fd插入到eventpoll的就绪队列中,发出信号唤醒等待队列中的进程等等……基于回调的epoll远比基于轮询的select/poll高效!
    3. epoll_wait: 检测就绪队列是否为空,如果不为空,就将就绪队列中的信息拷贝到用户空间。如果为空,进入eventpoll的等待队列,设置进程为睡眠状态,等待被唤醒。

说明:

上面的讨论省略了很多细节,比如内核编程中等待队列的相关认识,poll机制,操作数据结构时的加锁保护,边界情况,边缘触发与水平触发,slab等等内核编程中的细节。但是能够帮助你理清epoll的基本脉络,详细的讨论可以访问以下链接。

  • http://blog.csdn.net/tianmohust/article/details/6743987
  • https://segmentfault.com/a/1190000003063859
  • https://www.nowcoder.com/discuss/26226?type=1&order=4&pos=2&page=1
原创粉丝点击