python中的selectors模块
它的功能与linux的epoll,还是select模块,poll等类似;实现高效的I/O multiplexing, 常用于非阻塞的socket的编程中;
python文档:https://docs.python.org/3/library/selectors.html
1. 模块定义了一个 BaseSelector的抽象基类, 以及它的子类,包括:SelectSelector, PollSelector, EpollSelector, DevpollSelector, KqueueSelector.
另外还有一个DefaultSelector类,它其实是以上其中一个子类的别名而已,它自动选择为当前环境中最有效的Selector,所以平时用 DefaultSelector类就可以了,其它用不着。
2. 模块定义了两个常量,用于描述 event Mask
EVENT_READ : 表示可读的; 它的值其实是1;
EVENT_WRITE: 表示可写的; 它的值其实是2;
3. 模块定义了一个 SelectorKey类, 一般用这个类的实例 来描述一个已经注册的文件对象的状态, 这个类的几个属性常用到:
fileobj: 表示已经注册的文件对象;
fd: 表示文件对象的描述符,是一个整数,它是文件对象的 fileno()方法的返回值;
events: 表示注册一个文件对象时,我们等待的events, 即上面的event Mask, 是可读呢还是可写呢!!
data: 表示注册一个文件对象是邦定的data;
4. 最后说说抽象基类中的方法;
register(fileobj, events, data=None)
作用:注册一个文件对象。
参数:
fileobj——即可以是fd 也可以是一个拥有fileno()方法的对象;
events——上面的event Mask 常量;
data返回值: 一个SelectorKey类的实例;
unregister(fileobj)
作用: 注销一个已经注册过的文件对象;
返回值:一个SelectorKey类的实例;
modify(fileobj, events, data=None)
作用:用于修改一个注册过的文件对象,比如从监听可读变为监听可写;它其实就是register() 后再跟unregister(),但是使用modify( ) 更高效;
返回值:一个SelectorKey类的实例;
select(timeout=None)
作用: 用于选择满足我们监听的event的文件对象;
返回值: 是一个(key, events)的元组, 其中key是一个SelectorKey类的实例, 而events 就是 event Mask(EVENT_READ或EVENT_WRITE,或者二者的组合)
close()
作用:关闭 selector。 最后一定要记得调用它, 要确保所有的资源被释放;
get_key(fileobj)
作用: 返回注册文件对象的 key;
返回值 :一个SelectorKey类的实例;
根据socket通信实例熟悉一下selectors模块
socket server端代码:
#!/usr/bin/python3
# -*- coding: utf-8 -*-
"""
IO多路复用之selectors模块
selectors模块帮我们选择当前操作系统平台下最合适的IO多路复用机制
有epoll就用epoll
有poll就用poll
有select就用select
"""
import selectors
import socket
def to_accept(sock, mask):
conn, addr = sock.accept()
conn.setblocking(False)
sel.register(fileobj=conn, events=selectors.EVENT_WRITE, data=to_read)
def to_read(conn, mask):
try:
recvs = conn.recv(1024)
if not recvs:
sel.unregister(fileobj=conn)
conn.close()
return
print(recvs.decode(encoding='utf-8'))
sel.unregister(fileobj=conn)
wdict[conn] = b'%s' % (recvs, )
sel.register(fileobj=conn, events=selectors.EVENT_WRITE, data=to_write)
except ConnectionResetError:
sel.unregister(fileobj=conn)
conn.close()
return
def to_write(conn, mask):
# print(mask) # EVENT_READ 值为1, EVENT_WRITE 值为2
conn.sendall(wdict.get(conn))
wdict.pop(conn)
sel.unregister(fileobj=conn)
sel.register(fileobj=conn, events=selectors.EVENT_READ, data=to_read)
sk = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM)
sk.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sk.bind(('', 8080))
sk.listen(32)
sk.setblocking(False)
sel = selectors.DefaultSelector()
sel.register(fileobj=sk, events=selectors.EVENT_READ, data=to_accept)
wdict = dict()
while 1:
events = sel.select(timeout=None)
for sel_obj, mask in events:
callback = sel_obj.data
callback(sel_obj.fileobj, mask)
socket client 端
#!/usr/bin/python3
# -*- coding: utf-8 -*-
import socket
import threading
def my_client():
sk = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM)
sk.connect(('localhost', 8080))
while 1:
sk.send(b'hi')
msg = sk.recv(1024)
print(msg)
for i in range(10):
threading.Thread(target=my_client).start()
分类:
python
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架