python中的epoll
来源:互联网 发布:iphone4s可以用4g网络 编辑:程序博客网 时间:2024/06/04 17:53
epoll和select、pool都属于IO多路复用机制。
I/O多路复用:通过一种机制,可以监视多个描述符,一旦某个描述符就绪(可读或可写),就能够通知程序进行相应的读写操作。(epoll采用事件通知机制)。
下表我们对比select模块中的select()、pool、epoll的优缺点以及机制。(有一个共同的优点就是在单进程中完成了并发)
以epoll的简单使用代码进行理解:
使用epoll搭建一个简单的TCP服务器为例:
功能一:等待客户端的进入
import select as selimport socket as sock#创建负责接收新客户端来访的套接字(TCP模式)server_socket = sock.socket(sock.AF_INET, sock.SOCK_STREAM)#重复绑定套接字端口,避免服务器异常关闭时再次启动的等待server_socket.setsockopt(sock.SOL_SOCKET, sock.SO_REUSEADDR, 1)#服务器绑定端口号server_socket.bind(('', 7788))#切换套接字状态server_socket.listen(10)#创建epoll对象check_atttr = sel.epoll()#注册套接字的文件描述符以及触发状态和触发机制(因为服务器只负责接收客户信息,所以只需要检测是否可以读)check_atttr.register(server_socket.fileno(), sel.EPOLLIN|sel.EPOLLET)#循环,使用事件通知机制检测,并对结果进行判断处理while True: #epoll.poll()等待已注册的状态就绪的文件描述符并返回一个可迭代对象,这里与select() poll()不同,是等待不是轮询. #如果没有状态就绪的文件描述符,那么就会堵塞等待 check_result = check_atttr.poll() print(check_result)
尝试使用多个客户端连接的结果为:
[(3, 1)][(3, 1)][(3, 1)][(3, 1)]............
这里会返回一个固定的列表,里面有一个元祖,其中3代表,我们创建的套接字的fileno,1代表这个套接字的状态,也就是说当输出这个结果的时候,我们创建的套接字就被激活了,我们可以使用下一步,accept(),然后创建新的为客户端服务的套接字。
可以通过一个图来理解:
对代码继续进行完善(创建为一个客户端服务的套接字):
import select as selimport socket as sock#创建负责接收新客户端来访的套接字(TCP模式)server_socket = sock.socket(sock.AF_INET, sock.SOCK_STREAM)#重复绑定套接字端口,避免服务器异常关闭时再次启动的等待server_socket.setsockopt(sock.SOL_SOCKET, sock.SO_REUSEADDR, 1)#服务器绑定端口号server_socket.bind(('', 7788))#切换套接字状态server_socket.listen(10)#创建epoll对象check_atttr = sel.epoll()#注册套接字的文件描述符以及触发状态和触发机制(因为服务器只负责接收客户信息,所以只需要检测是否可以读)print('----1------')check_atttr.register(server_socket.fileno(), sel.EPOLLIN|sel.EPOLLET)print('-----2-----')#通过文件描述符作为键,套接字或地址作为值的字典s2c_scoket = {}s2c_addr = {}#循环,使用事件通知机制检测,并对结果进行判断处理while True: #epoll.poll()等待已注册的状态就绪的文件描述符并返回一个可迭代对象,这里与select() poll()不同,是等待不是轮询. #如果没有状态就绪的文件描述符,那么就会堵塞等待 check_result = check_atttr.poll() #print(check_result) 如果返回的套接字文件描述符和server_socket相等,就是说有新的客户端与我们进行了链接 for fd, event in check_result: if fd == server_socket.fileno(): #完成与客户端的链接,并创建新的套接字 server2cilent, addr = server_socket.accept() #要等待新的套接字的通知,因此将新套接字注册到epoll中 check_atttr.register(server2cilent.fileno(), sel.EPOLLIN|sel.EPOLLET) #如果我们依然是通过文件描述符来确定是哪个server2cilent,这时候直接使用 #server2cilent只能找到最后创建的一个server2cilent,所以我们使用键值对保存套接字 s2c_scoket[server2cilent.fileno()] = server2cilent s2c_addr[server2cilent.fileno()] = addr #此时如果有一个非服务器套接字准备好,那么会得到这个套接字的文件描述符,因为只有两种套接字 else: #通过键找到对应的值即套接字,堵塞等待这个客户端的消息到来 recvData = s2c_scoket[fd].recv(1024) if len(recvData) > 0: print('来自于%s的消息:%s'%(str(s2c_addr[fd]), recvData)) else: print('%s已经与服务器断开了连接....'%str(s2c_addr[fd])) s2c_scoket[fd].close() #因为这个客户端已经断开了连接,当前这个套接字也就没有保存的意义,避免占用空间,将其注销,并删除掉键值对 check_atttr.unregister(fd) del s2c_scoket[fd] del s2c_addr[fd]check_atttr.close()
附:几种eventmask
最后的疑问是:EPOLLOUT怎么用??
0 0
- python中的epoll
- python epoll
- Python Epoll
- python 使用 epoll
- python epoll开发服务器
- 经典python epoll(ET)
- python select.epoll
- python下使用epoll
- python下使用epoll
- python select poll epoll
- Epoll 使用中的疑惑
- linux中的epoll机制
- linux中的epoll机制
- linux中的epoll机制
- UDT中的epoll
- Using Linux epoll with Python
- 在python中使用epoll
- Epoll在Nio中的实现
- Android WebView 与JS的数据交互
- Python输入 raw_input()/input() 与 sys.stdin.readline()的不同
- 压缩感知重构算法之正则化正交匹配追踪(ROMP)
- 给游戏任务换装备的代码心得
- UVALive
- python中的epoll
- 《算法导论》习题2.1-3
- 十二、AspectJ切入点语法详解
- JavaScript数据类型
- 标题: 幻方填空
- shiro基础学习(三) shiro授权
- GUI_优化HelloWorld窗体案例代码
- 如何把char转成int
- 2016华成杯赛后总结