python epoll简单模型(协程的实现方式)

来源:互联网 发布:从此山高水长君不必知 编辑:程序博客网 时间:2024/06/08 05:14

EPOLLIN (可读)
EPOLLOUT (可写)
EPOLLET (ET模式)
epoll对文件描述符的操作有两种模式:LT(level trigger)和ET(edge trigger)。LT模式是默认模式,
LT模式与ET模式的区别如下:
LT模式:当epoll检测到描述符事件发⽣并将此事件通知应⽤程序,应⽤程序可以不⽴即处理该事件。下次调⽤e
poll时,会再次响应应⽤程序并通知此事件。
ET模式:当epoll检测到描述符事件发⽣并将此事件通知应⽤程序,应⽤程序必须⽴即处理该事件。如果不处理
,下次调⽤epoll时,不会再次响应应⽤程序并通知此事件。
LT类似于故障不除,红灯不灭,
ET类似于只说⼀次,不再赘述。
文件描述符
在UNIX/LINUX中,一切皆文件

import socketimport select# 创建套接字s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)# 设置可以重复使⽤绑定的信息s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR,1)# 绑定本机信息s.bind(("",7788))# 变为被动s.listen(10)# 将套接字设置为⾮阻塞模式s.setblocking(False)# 创建⼀个epoll对象epoll = select.epoll()# 测试,⽤来打印套接字对应的⽂件描述符# print(s.fileno())# print(select.EPOLLIN|select.EPOLLET)# 注册事件到epoll中# epoll.register(fd[, eventmask])# 注意,如果fd已经注册过,则会发⽣异常# 将创建的套接字添加到epoll的事件监听中epoll.register(s.fileno(), select.EPOLLIN|select.EPOLLET)connections = {}addresses = {}# 循环等待客⼾端的到来或者对⽅发送数据while True:# epoll 进⾏ fd 扫描的地⽅ -- 未指定超时时间则为阻塞等待epoll_list = epoll.poll()# 对事件进⾏判断for fd, events in epoll_list:# print fd# print events# 如果是socket创建的套接字被激活if fd == s.fileno():new_socket, new_addr = s.accept()print('有新的客⼾端到来%s' % str(new_addr))# 将 conn 和 addr 信息分别保存起来connections[new_socket.fileno()] = new_socketaddresses[new_socket.fileno()] = new_addr# 向 epoll 中注册 新socket 的 可读 事件epoll.register(new_socket.fileno(), select.EPOLLIN|select.EPOLLET)# 如果是客⼾端发送数据elif events == select.EPOLLIN:# 从激活 fd 上接收recvData = connections[fd].recv(1024).decode("utf-8")if recvData:print('recv:%s' % recvData)else:# 从 epoll 中移除该 连接 fdepoll.unregister(fd)# server 侧主动关闭该 连接 fdconnections[fd].close()print("%s---offline---" % str(addresses[fd]))del connections[fd]del addresses[fd]