epoll和select原理

概念准备

任务队列:这里指线程的任务队列,维护着需要CPU运行的线程。

等待队列:socket文件描述符上的一个数据结构,如果想要监听socket是否数据过来,就需要将进程放到等待队列中,如果有数据产生,那么就将线程从等待队列中移除,重新放到任务队列里面,等待CPU进行调度。

socket描述符:可以理解为一个链接就可以转化为一个socket描述符

select

select的系统调用,主要的参数是一个fds数组
fds:存放需要监听的socket链接的数组

调用select的核心步骤

假如fds有socket1、socket2、socket3

1、将当前的调用进程注册到socket1、socket2、socket3各自的等待队列中,并且将当前进程从CPU的任务队列中移除

2、select会轮询的查看socket1、socket2、socket3的缓冲区中是否有数据到来

3、如果存在数据,就会将等待队列中的进程唤醒,将进程从等待队列中移除,加入到任务队列里面

4、但是进程不知道是哪个socket准备好了,因此他需要循环fds,然后对数据进行处理

图解

在这里插入图片描述
在这里插入图片描述

缺陷

  1. 每次调用select都会将进程重新注册到socket的等待队列中去
  2. 需要进行两次循环调用。
    1. 第一次是将进程注册到socket的等待队列
    2. 第二次是查看哪个socket的缓冲区中有数据

poll

poll的实现思路跟select基本差不多,只不过是将fds的数据结构改为链表。
打破了个数的限制,select限制最多可以监听1024个socket,如果想要修改,需要重新编译内核。

epoll

epoll是对select的缺陷进行优化

1、不需要重新注册,只需要注册一次感兴趣的事件

2、只需要一次循环调用即可

优化措施

  • epoll_create:内核会创建一个 eventpoll 对象(专用的文件描述符,也就是程序中 epfd 所代表

    的对象)eventpoll 对象也是文件系统中的一员,和 socket 一样,它也会有等待队列。

  • epoll_ctl:添加待监控的socket

    如果通过 epoll_ctl 添加 sock1、sock2 和 sock3 的监视,内核会将三个 socket 添加到 eventpoll

    监听队列。

  • epoll_wait:阻塞等待

    进程 A 运行到了 epoll_wait 语句之后,进程A会进入eventpoll 的等待队列。

epoll_create

主要是创建一个eventpoll对象,他和socket一样,也有等待队列

eventpoll对象主要的数据结构

  • rbr:红黑树,存放需要监听的socket
  • rdllist:一个双向链表,存放已经发生IO事件的socket
  • poll_wait:等待队列,进程就是注册到poll_wait中

epoll_ctl

添加待监控的socket

会将待监控的socket添加到eventpoll对象rbr中,因为rbr是一个红黑树,所以epoll监听的连接数,可以远远大于1024个

当socket收到数据后,中断程序会将收到数据的socket添加到eventpoll的就绪队列rdlist

epoll_wait

当程序执行到epoll_wait时,如果rdlist非空则返回,如果rdlist为空,阻塞进程

当socket接收到数据,中断程序一方面将其插入rdlist,另一方面唤醒eventpoll等待队列中的进程,进程A再次进入内核的工作队列。进程A进行运行状态。

图解

可以认为eventpoll当一个中介的作用

在这里插入图片描述

优化概括

  1. 使用红黑树rbr,打破了select监听socket个数的限制。
  2. 将要监听的socket存放到eventpoll的rbr中,然后将eventpoll注册到各个socket的等待队列中,使得eventpoll当一个中介的作用,因此只需要注册一次即可。
  3. 使用rdllist存放已经发生事件的socket,无需重复遍历要监听的socket。

ET和LT

  • ET边沿触发:有数据进入到缓冲区中,那么就会触发事件,如果在这次事件中,没有读完缓冲区的数据,那么下次再来读,也不会读取数据,只有当数据再次到缓冲区中才可以再次处理。

  • LT水平触发:缓冲区中有数据,就会一直读取,直到缓冲区中没有数据为止。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

默默行路

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值