epoll并发
Posted zuzhuangmengxiang
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了epoll并发相关的知识,希望对你有一定的参考价值。
epoll仅限Linux或Unix系统(服务器)。
片面讲epoll并发原理:1.数据共享(内存映射(mmap)技术),即client_socket_list和操作系统共享,省去拷贝fb给操作系统的时间
2.事件监听(基于事件的就绪通知方式),不再是一直遍历客户端套接字列表来得知哪个套接字有数据,而是哪个套接字有数据直接传给操作系统。
epoll实现http服务器:
1 import socket 2 import re 3 import select 4 5 6 def service_client(client_socket, requests): 7 """为这个客户端返回数据""" 8 # 1.接收浏览器发送过来的请求 9 # request = client_socket.recv(1024).decode(‘utf-8‘) 10 # 将浏览器请求的头部信息,根据换行拆分成一个列表 11 headers = requests.splitlines() 12 # print(headers[0]) # GET /XXX/XXXX HTTP/1.1 13 ret = re.match(r‘[^/]+(/[^ ]*)‘, headers[0]) 14 # print(ret.group()) 15 file_name = ‘‘ 16 if ret: 17 # 符合正则的值为GET /XXX/XXX和/XXX/XXX 取后面这个group(1) 18 file_name = ret.group(1) 19 # 如果浏览器请求的是127.0.0.1(也就是只有一个/),那么让浏览器显示主页(index.html) 20 if file_name == ‘/‘: 21 file_name = ‘/index.html‘ 22 23 # 2.返回http格式的数据给浏览器 24 try: 25 f = open(‘jQuery响应式网站导航菜单‘+file_name, ‘rb‘) 26 except: 27 # 如果浏览器访问的页面不存在,则返回404 28 response = "HTTP/1.1 404 " 29 response += ‘Content-Type: text/html;charset=utf-8 ‘ 30 response += ‘ ‘ 31 response += "您所访问的地址或文件不存在" 32 # 发送网页的headers 33 client_socket.send(response.encode(‘utf-8‘)) 34 else: 35 # 2.1 准备发送给浏览器的header 36 html_content = f.read() 37 f.close() 38 response = "HTTP/1.1 200 OK " 39 response += ‘Content-Type: text/html;charset=utf-8 ‘ 40 response += ‘Content-Length: %d ‘ % len(html_content) 41 response += ‘ ‘ 42 # 发送网页的headers 43 client_socket.send(response.encode(‘utf-8‘)) 44 45 # 发送网页的body 46 client_socket.send(html_content) 47 48 # 关闭套接字 49 # client_socket.close() 50 51 52 def main(): 53 """用来完成整体的控制""" 54 # 1.创建套接字 55 tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 56 tcp_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 57 58 # 2.绑定 59 tcp_server_socket.bind((‘‘, 7788)) 60 61 # 3.设置为被动监听 62 tcp_server_socket.listen(128) 63 tcp_server_socket.setblocking(False) # 将套接字变为非堵塞 64 65 # 创建一个epoll对象 66 epl = select.epoll() 67 68 # 将监听套接字对应的fd注册到epoll中 69 epl.register(tcp_server_socket.fileno(), select.EPOLLIN) 70 71 fd_evevt_dict = dict() 72 while True: 73 # 默认会堵塞,直到os检测到数据到来,通过事件通知方式告诉这个程序,此时才会借堵塞 74 # [(fd,event), (fd, event)...] 75 # fd:套接字对应的文件描述符,evevt:这个文件描述符到底是什么事件 76 fd_evevt_list = epl.poll() 77 for fd, event in fd_evevt_list: 78 if fd == tcp_server_socket.fileno(): 79 # 4.等待客户端连接 80 new_socket, client_adress = tcp_server_socket.accept() 81 epl.register(new_socket.fileno(), select.EPOLLIN) 82 fd_evevt_dict[new_socket.fileno()] = new_socket 83 # 除了监听套接字,剩下的都是客户端套接字 84 elif event == select.EPOLLIN: 85 # 判断已经链接的客户是否有数据发送过来 86 client_socket = fd_evevt_dict[fd] 87 recv_data = client_socket.recv(1024).decode(‘utf-8‘) 88 if recv_data: 89 service_client(client_socket, recv_data) 90 else: 91 client_socket.close() 92 epl.unregister(fd) 93 del fd_evevt_dict[fd] 94 95 # 关闭监听套接字 96 tcp_server_socket.close() 97 98 99 if __name__ == ‘__main__‘: 100 main()
具体epoll详解参照:https://blog.csdn.net/xiajun07061225/article/details/9250579
以上是关于epoll并发的主要内容,如果未能解决你的问题,请参考以下文章