Python Epoll

探究Python Epoll实现和对比Select

Epoll的实现原理
Epoll采用事件触发的机制,通过用户创建Epoll对象并注册事件宏监听具体事件,以达到事件发生时触发任务的执行。
为了更好得理解Epoll的机制,我简单得理解为Socket的交互本身就是两个读、写缓冲区,然后Epoll就是监听这两个缓冲区的数据非空、非满的状态,非空代表有数据读入,非满代表可以有数据写入,然后Epoll检测到用户注册的事件发生以后开始执行对应的IO操作。

对比Select
Select同样是采用了监听触发的机制去取代最原始的为每一个连接新建一个线程的处理方式。但是Select的原理是利用函数监听一个可读队列和一个可写队列。当select监听到有事件发生时,它并不知道是哪个客户端的事件,因此需要做一次轮询,查找发生的对象,然后再进行后续的处理,其次是select也有最大监听描述符数量的限制,而epoll是没有这个限制的,当然epoll也是有可优化的点在的,比如如何异步去执行IO操作而不是阻塞等待返回再去检测epoll 的函数返回。这样可以更高效的处理客户端的数据。

为了充分探究每一个事件操作如何影响epoll监听的描述符,我在下面的程序运行中做了一系列的打印,得出了以下的结论
1. 在服务端启动没有客户端连接的情况下,程序阻塞在 epoll_fd = select.epoll( ) 处,此时服务端等待客户端连接才能使程序往下跑;
2.客户端发起连接请求,epoll监听到了事件,epoll_list打印为[ (3,1)],执行操作服务端接收客户端的连入请求并注册客户端的epoll事件;
3. 客户端请求发送数据到服务端,在while循环中。epoll_list第一次打印为[ (5,1)],可读事件触发,此时服务端接受数据,并更改客户端的监听事件为可写,为了后续服务端回传相同的数据给客户端做准备,循环的第二次打印为[(5,4)],可写事件触发,服务端将储存在变量中的数据回传给客户端,并重新更改客户端的epoll监听事件为可读事件,监听客户端下一次数据的发送。
4. 整个过程中,需要有三个变量分别保存连接的客户端,客户端发送的数据这两个必要数据。
注:epoll_list里面存放的是文件描述符编号以及事件返回值

补充解释:
Epoll的触发方分为水平触发(LT)和边缘触发(ET)
水平触发是两个缓冲区只要存在没有被读取的数据存在就一定会使epoll触发通知,它监听的是数据;
边缘触发是两个缓冲区如果发生了数据的变化才会使epoll触发通知,并不在乎数据,它监听的是变化;
举个栗子:
如果读入缓冲区新增了一个100k的数据,两种触发方式都一定会工作使epoll触发通知,此时如果程序只是拿了其中50k的数据,还有残存50k在缓冲区内,这时候水平触发一定会继续通知,而边缘触发就不会。

贴上测试的代码分享:
服务端代码

#!/usr/bin/python
#-*- coding:utf-8 -*-

import socket
import select, errno

if __name__ == "__main__":
    try:
        # 创建 TCP socket 作为监听 socket
        listen_fd = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值