python epoll

事件驱动模型

事件驱动编程是一种网络编程范式,程序的执行流由外部事件来决定。它的特点是包含一个事件循环,程序可能关注多种事件,在事件循环中不断去轮询监控各种事件,如果某个事件发生,则调用该事件注册的回掉函数。

影响事件驱动模型的两点

轮询各种事件的效率:如果时间循环在查询某个事件时阻塞了,那么当其它事件到达时势必无法及时响应,影响性能。

回掉函数的效率:如果回掉函数在处理某个事件时用时较长,那么同样会使得事件循环无法及时响应其它事件。

epoll

epoll的作用是提升事件循环查询“io事件”的效率,他允许用户进程同时监听多个文件描述符的io事件即io多路复用。同时epoll在实现上是十分高效的,相对于poll/select,epoll使得进程可以监控更多的文件描述符。epoll采用注册机制,在内核中保存用户关注的文件描述符(红黑树保存),不像select一样每次都需要传入所有的文件描述符,效率更高(减少了从用户空间向内核空间的拷贝)。epoll不像select一样会在内核中轮询所有的文件描述符(低效的),epoll会在不同文件描述符对应的设备的等待队列中添加一个回调函数,在回掉函数中将对应的文件描述符添加至epoll的rdlist队列(高效的),当进程调用epoll_wait时,内核检查该队列是否为空,如果是空则阻塞进程,如果不为空则将该队列拷贝至用户空间,并返回该函数。

epoll的两种触发方式

水平触发:只要文件描述符仍可读、可写则每次调用epoll_wait时都会返回该文件描述符。

边缘触发:当文件描述符返回给用户进程一次后,如果没有新的数据到达fd对应的读缓冲区、或fd对应的写缓冲区没有新的空间产生,则下次调用epoll_wait时是不会返回该fd的。

水平触发时用户进程会更简单,可以先读一部分数据,处理完后再读一部分数据。而边缘出发时,用户进程更严格,每次应该读出所有数据,否则如果该fd上不再有数据到达,则未读取的数据就会丢失。

实现原理:epoll将rdlist copy给用户空间后,会检查各个fd的触发方式,如果是水平触发则epoll会将该fd重新放回rdlist,如果是边缘出发则不会再放回。而在copy之前会调用各fd的poll方法,获取fd最新的事件掩码,与用户注册的该fd关注的事件掩码对比,如果存在关注事件,则拷贝,如果不存在则丢弃(如果fd是因水平出发重新放回rdlist的,而用户进程已经读完了fd的数据完,则该步骤可以发现并处理这种情况)。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值