18.4.selectors
— 高层 I/O 多路复用 ¶
3.4 版新加入。
18.4.1. 介绍 ¶
这个模块允许高层高效的 I/O 多路复用,建立在 选择
模块原函数基础之上。鼓励用户使用此模块,除非他们想精确控制系统级别原函数的使用。
它定义了 BaseSelectorr
抽象基类,以及几种具体的实现 ( KqueueSelectorr
, EpollSelectorr
...),可用多个文件对象上等待 I/O 准备就绪的通知。在下文中,"文件对象"指任何有 fileno()
方法或原始文件描述符的对象。请参阅 文件对象。
DefaultSelector
是当前平台上可用的最有效实现的别名︰ 这应该是大多数用户的默认选择。
注意
支持的文件对象的类型取决于平台︰ 在 Windows 上,支持套接字,但不支持管道,而在 Unix 上,两者都受支持 (某些其他类型可能也支持,比如 fifo 或特殊文件设备)。
令请参阅
select
- 低层 I/O 多路复用模块。
18.4.2. 类 ¶
类层次结构︰
BaseSelector
+-- SelectSelector
+-- PollSelector
+-- EpollSelector
+-- DevpollSelector
+-- KqueueSelector
在下文中,事件 是指那些等待I/O 事件的给定的文件对象的位掩码。它可以是下面的模块常量的组合︰
Constant Meaning EVENT_READ
Available for read EVENT_WRITE
Available for write
- class
selectors.
SelectorKey
¶ SelectorKey
是一个用来将文件对象关联到其底层文件描述符,选定的事件掩码和附加的数据的namedtuple
。它由BaseSelector
的几种方法返回。-
fileobj
¶ 注册的文件对象。
-
fd
¶ 底层的文件描述符。
-
events
¶ 该文件对象必须等待的事件。
-
data
¶ 可选的与此文件对象相关联的不透明数据︰ 例如,这可以用来存储每个客户端的会话 id。
-
- class
selectors.
BaseSelector
¶ BaseSelector
用来等待多个文件对象的I/O 事件的准备。它支持文件流注册、 注销和带可选超时值的等待这些流的 I/O 事件的方法。它是一个抽象的基类,因此不能实例化。使用DefaultSelector
来替代 或者用SelectSelector
,KqueueSelector
等。如果您想要明确使用一种实现,和您的平台支持它。BaseSelector
和其具体的实现支持 上下文管理器 协议。- abstractmethod
register
(fileobj, events, data=None)¶ 注册一个文件对象到选择器来监视它的 I/O 事件。
fileobj 是要监视的文件对象。它可能是一个整型文件描述符或有
fileno()
方法的对象。events 是要监视的事件的位掩码。data 是不透明的对象。这返回一个新的
SelectorKey
实例,或者因无效的事件掩码或文件描述符抛出ValueError
错误,或者如果文件对象已注册则抛出KeyError
错误。
- abstractmethod
unregister
(fileobj)¶ 从选择器注销一个文件对象并移除对它的监视。文件对象被注销前应先关闭。
fileobj 必须是先前注册过的文件对象。
这返回关联的
SelectorKey
实例,或者如果 fileobj未注册则抛出KeyError
错误。如果 fileobj 无效则抛出ValueError
错误(例如,它没有fileno()
方法或其fileno()
方法有无效的返回值)。
-
modify
(fileobj, events, data=None)¶ 更改已注册的文件对象的监视事件或附加数据。
这就相当于先
BaseSelector.unregister(fileobj)()
再BaseSelector.register (fileobj, events, data)()
,只是,它可以更有效地执行。这返回一个新的
SelectorKey
实例,或者因无效的事件掩码或文件描述符抛出ValueError
错误,或者如果文件对象已注册则抛出KeyError
错误。
- abstractmethod
select
(timeout=None)¶ 等到一些已注册的文件对象准备好或者超时。
如果
timeout > 0
,会指定最长的等待时间,以秒为单位。如果timeout < = 0
,调用不会阻塞并会报告目前准备好的文件对象。如果 timeout 是None
,调用将会阻塞直到一个监视的文件对象准备好。这将返回一个以
(key, events)
元组为元素的列表,每一个元祖代表一个准备好的文件对象。key 是对应于一个准备好的文件对象的
SelectorKey
实例。events 是该文件对象上准备好的事件位掩码。注意
如果当前进程接收到信号,此方法可以在超时前或任何文件对象准备好前返回:在这种情况下,将返回一个空列表。
3.5 版本中的更改︰当被一个信号中断时,如果信号处理程序不抛出异常 (见 PEP 475 原因),现在选择器再次重新计算超时,而不是在超时前返回一个空的事件列表。
-
close
()¶ 关闭选择器。
这个必须调用以确保所有底层资源被释放。一旦选择器被关闭就不能再使用。
-
get_key
(fileobj)¶ 返回一个与已注册的文件对象关联的键值。
这返回关联此文件对象的
SelectorKey
实例,或如果文件对象未注册则抛出KeyError
错误。
- abstractmethod
get_map
()¶ 返回文件对象到选择器键值的映射。
这将返回一个已注册的文件对象到与其关联的
SelectorKey
实例的映射的Mapping
实例。
- abstractmethod
- class
selectors.
DefaultSelector
¶ 默认选择器类使用在当前平台上可用的最有效的实现。这应该是大多数用户的默认选择。
- class
selectors.
SelectSelector
¶ 基于
select.select()
的选择器。
- class
selectors.
PollSelector
¶ 基于
select.poll()
的选择器。
- class
selectors.
EpollSelector
¶ 基于
select.epoll()
的选择器。-
fileno
()¶ 这将返回底层的
select.epoll()
对象所使用的文件描述符。
-
- class
selectors.
DevpollSelector
¶ 基于
select.devpoll()
的选择器。-
fileno
()¶ 这将返回底层的
select.devpoll()
对象所使用的文件描述符。
3.5版本中新加入。
-
- class
selectors.
KqueueSelector
¶ 基于
select.kqueue()
的选择器。-
fileno
()¶ 这将返回底层的
select.kqueue()
对象所使用的文件描述符。
-
18.4.3. 示例 ¶
这里是一个简单的回显服务器的实现︰
import selectors
import socket
sel = selectors.DefaultSelector()
def accept(sock, mask):
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()
for key, mask in events:
callback = key.data
callback(key.fileobj, mask)