On this page
selectors—高级 I/O 多路复用
3.4 版的新Function。
源代码: Lib/selectors.py
Introduction
此模块允许在select模块 Primitives 的基础上进行高层且高效的 I/O 复用。鼓励用户改用此模块,除非他们希望对使用的 OS 级 Primitives 进行精确控制。
它定义了一个BaseSelector抽象 Base Class,以及几个具体的实现(KqueueSelector,EpollSelector…),可用于 await 多个文件对象的 I/O 准备就绪通知。在下文中,“文件对象”是指具有fileno()
方法或原始文件 Descriptors 的任何对象。参见file object。
DefaultSelector是当前平台上可用的最高效实现的别名:这应该是大多数用户的默认选择。
Note
支持的文件对象的类型取决于平台:在 Windows 上,支持套接字,但不支持管道,而在 Unix 上,两者都受支持(还可以支持某些其他类型,例如 fifos 或特殊文件设备)。
See also
低级 I/O 多路复用模块。
Classes
Classes hierarchy:
BaseSelector
+-- SelectSelector
+-- PollSelector
+-- EpollSelector
+-- DevpollSelector
+-- KqueueSelector
在下面,* events *是按位掩码,指示应在给定文件对象上 await 哪些 I/O 事件。它可以是以下模块常量的组合:
Note
Constant | Meaning |
---|---|
EVENT_READ |
可供阅读 |
EVENT_WRITE |
可写 |
类别
selectors.
SelectorKey
- SelectorKey是namedtuple,用于将文件对象与其基础文件 Descriptors,选定的事件掩码和附加数据相关联。它由几种BaseSelector方法返回。
fileobj
- 文件对象已注册。
fd
- 基础文件 Descriptors。
events
- 必须在此文件对象上 await 的事件。
data
- 与此文件对象关联的可选不透明数据:例如,可以用于存储每个 Client 端会话 ID。
类别
selectors.
BaseSelector
- BaseSelector用于 await 多个文件对象的 I/O 事件就绪。它支持文件流注册,注销和 await 这些流上的 I/O 事件的方法,并具有可选的超时时间。这是一个抽象的 Base Class,因此无法实例化。如果要专门使用实现,并且平台支持该实现,则使用DefaultSelector或SelectSelector,KqueueSelector等之一。 BaseSelector及其具体实现支持context manager协议。
抽象方法
register
(* fileobj ,事件, data = None *)- 注册文件对象以供选择,并监视其 I/O 事件。
- fileobj *是要监视的文件对象。它可以是整数文件 Descriptors,也可以是具有
fileno()
方法的对象。 * events *是要监视的事件的按位掩码。 * data *是不透明的对象。
这将返回一个新的SelectorKey实例,或者在事件掩码或文件 Descriptors 无效的情况下引发ValueError,如果文件对象已被注册则返回KeyError。
- 抽象方法
unregister
(* fileobj *)- 从选择中取消注册文件对象,将其从监视中删除。文件对象在关闭之前应先注销。
- fileobj *必须是先前注册的文件对象。
这将返回关联的SelectorKey实例,如果未注册* fileobj ,则引发KeyError。如果 fileobj *无效(例如,它没有fileno()
方法或它的fileno()
方法具有无效的返回值),它将引发ValueError。
modify
(* fileobj , events , data = None *)- 更改注册文件对象的监视事件或附加数据。
这等效于BaseSelector.unregister(fileobj)()
后跟BaseSelector.register(fileobj, events, data)()
,但可以更有效地实现它。
这将返回一个新的SelectorKey实例,或者在事件掩码或文件 Descriptors 无效的情况下引发ValueError,或者在未注册文件对象的情况下返回KeyError。
- 抽象方法
select
(超时=无)- await 直到某些已注册的文件对象准备就绪,或者超时到期。
如果timeout > 0
,则指定最大 await 时间,以秒为单位。如果timeout <= 0
,则该调用将不会阻塞,并且将报告当前准备就绪的文件对象。如果* timeout *为None
,则调用将阻塞,直到被监视的文件对象准备就绪为止。
这将返回一个(key, events)
Tuples 的列表,每个就绪文件对象一个。
- key *是与就绪文件对象相对应的SelectorKey实例。 * events *是此文件对象上准备好的事件的位掩码。
Note
如果当前进程收到 signal,则该方法可以在任何文件对象准备就绪或超时之前返回:在这种情况下,将返回一个空列表。
在版本 3.5 中进行了更改:现在,如果 signal 处理程序没有引发异常(请参阅 PEP 475),则被 signal break时,selectors 将被 signal break,并重新计算超时,而不是在超时之前返回空事件列表。
close
( )- 关闭 selectors。
必须调用它以确保释放任何基础资源。selectors 一旦关闭就不得使用。
get_key
(* fileobj *)- 返回与已注册文件对象关联的密钥。
这将返回与此文件对象关联的SelectorKey实例,如果未注册文件对象,则返回KeyError。
- 抽象方法
get_map
()- 返回文件对象到 selectors 键的 Map。
这将返回一个Mapping实例,该实例将注册的文件对象 Map 到其关联的SelectorKey实例。
类别
selectors.
DefaultSelector
- 默认 selectors 类,使用当前平台上可用的最高效实现。对于大多数用户,这应该是默认选择。
类别
selectors.
SelectSelector
- select.select()-based selector.
类别
selectors.
PollSelector
- select.poll()-based selector.
类别
selectors.
EpollSelector
- select.epoll()-based selector.
fileno
( )- 这将返回基础select.epoll()对象使用的文件 Descriptors。
类别
selectors.
DevpollSelector
- select.devpoll()-based selector.
fileno
( )- 这将返回基础select.devpoll()对象使用的文件 Descriptors。
3.5 版中的新Function。
类别
selectors.
KqueueSelector
- select.kqueue()-based selector.
fileno
( )- 这将返回基础select.kqueue()对象使用的文件 Descriptors。
Examples
这是一个简单的回显服务器实现:
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)