参考资料:https://www.cnblogs.com/gareth-yu/p/9097943.html
import selectors import socket sel = selectors.DefaultSelector() def accept(sock, mask): # sock相当于key.fileobj conn, addr = sock.accept() # Should be ready print('accepted', conn, 'from', addr) conn.setblocking(False) sel.register(conn, selectors.EVENT_READ, read) def read(conn, mask): data = conn.recv(1000) # Should be ready if data: print('echoing', repr(data), 'to', conn) conn.send(data) # Hope it won't block else: print('closing', conn) sel.unregister(conn) conn.close() sock = socket.socket() sock.bind(('localhost', 1234)) sock.listen(100) sock.setblocking(False) sel.register(sock, selectors.EVENT_READ, accept) while True: events = sel.select() # 根据系统是否支持,使用epoll还是select,优先epoll。默认阻塞,有活动连接就返回活动的连接列表 for key, mask in events: callback = key.data # 相当于回调accept callback(key.fileobj, mask) # key.fileobj相当于建立连接后的conn
select是不断轮询去监听的socket,socket个数有限制,一般为1024个(文件描述符为1024,该值可以修改);随着文件描述符数量增加,轮询一回成本增加。
poll采用轮询方式监听,只不过没有个数限制;
epoll不采用轮询方式去监听,而是当socket有变化时通过回调的方式主动告知用户进程;无最大链接数的限制
selector这个模块允许高级别和高效的I/O多路复用,建立在select模块之上,相当于epoll。如果不是对精确OS级别的原语控制,推荐使用这个模块
=============================
select是不断轮询去监听的socket,socket个数有限制,一般为1024个(文件描述符为1024,该值可以修改);随着文件描述符数量增加,轮询一回成本增加。
poll采用轮询方式监听,只不过没有个数限制;
epoll不采用轮询方式去监听,而是当socket有变化时通过回调的方式主动告知用户进程;无最大链接数的限制
selector这个模块允许高级别和高效的I/O多路复用,建立在select模块之上,相当于epoll。如果不是对精确OS级别的原语控制,推荐使用这个模块