selectors模块
此模块允许高级和高效的I / O多路复用,构建在select模块原语上。鼓励用户使用此模块,除非他们需要精确控制所使用的操作系统级原语。( 默认使用epoll,但由于Windows不支持epoll,如果在你的Windows上找不到epoll的话,就会用select) 它定义了一个抽象基类,有几个具体的实现工具(KqueueSelector, EpollSelector…),可以用于等待多个文件对象的I / O就绪通知。在下文中,file object” 指的是任何fileno() method,或一个原始文件的描述符。请参阅文件对象。BaseSelectorKqueueSelectorEpollSelectorfileno()
DefaultSelector 是别名到当前平台上可用的最有效的实现:这应该是大多数用户的默认选择
注意支持的文件对象类型取决于平台:在Windows上,支持套接字,但不支持管道,而在Unix上,支持两者(也可以支持其他类型,例如fifos或特殊文件设备)
实例- server端
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| import selectors from socket import *
def accept(sk,mask): conn,addr=sk.accept() sel.register(conn,selectors.EVENT_READ,read)
def read(conn,mask): try: data=conn.recv(1024) if not data: print('closing',conn) sel.unregister(conn) conn.close() return conn.send(data.upper()+b'_SB') except Exception: print('closing', conn) sel.unregister(conn) conn.close()
sk=socket() sk.setsockopt(SOL_SOCKET,SO_REUSEADDR,1) sk.bind(('127.0.0.1',8008)) sk.listen(5) sk.setblocking(False) sel=selectors.DefaultSelector() sel.register(sk,selectors.EVENT_READ,accept)
while True: events=sel.select() for sel_obj,mask in events: callback=sel_obj.data callback(sel_obj.fileobj,mask)
|
实例-client端
1 2 3 4 5 6 7 8 9 10 11 12 13
| import time import socket import threading def func(): sk = socket.socket() sk.connect(('127.0.0.1',8008)) sk.send(b'hello') time.sleep(3) print(sk.recv(1024)) sk.close()
for i in range(20): threading.Thread(target=func).start()
|