selectors—高级 I/O 多路复用

3.4 版的新Function。

源代码: Lib/selectors.py


Introduction

此模块允许在select模块 Primitives 的基础上进行高层且高效的 I/O 复用。鼓励用户改用此模块,除非他们希望对使用的 OS 级 Primitives 进行精确控制。

它定义了一个BaseSelector抽象 Base Class,以及几个具体的实现(KqueueSelectorEpollSelector…),可用于 await 多个文件对象的 I/O 准备就绪通知。在下文中,“文件对象”是指具有fileno()方法或原始文件 Descriptors 的任何对象。参见file object

DefaultSelector是当前平台上可用的最高效实现的别名:这应该是大多数用户的默认选择。

Note

支持的文件对象的类型取决于平台:在 Windows 上,支持套接字,但不支持管道,而在 Unix 上,两者都受支持(还可以支持某些其他类型,例如 fifos 或特殊文件设备)。

See also

  • select

  • 低级 I/O 多路复用模块。

Classes

Classes hierarchy:

BaseSelector
+-- SelectSelector
+-- PollSelector
+-- EpollSelector
+-- DevpollSelector
+-- KqueueSelector

在下面,* events *是按位掩码,指示应在给定文件对象上 await 哪些 I/O 事件。它可以是以下模块常量的组合:

Note

Constant Meaning
EVENT_READ 可供阅读
EVENT_WRITE 可写

这将返回一个新的SelectorKey实例,或者在事件掩码或文件 Descriptors 无效的情况下引发ValueError,如果文件对象已被注册则返回KeyError

这将返回关联的SelectorKey实例,如果未注册* fileobj ,则引发KeyError。如果 fileobj *无效(例如,它没有fileno()方法或它的fileno()方法具有无效的返回值),它将引发ValueError

这等效于BaseSelector.unregister(fileobj)()后跟BaseSelector.register(fileobj, events, data)(),但可以更有效地实现它。

这将返回一个新的SelectorKey实例,或者在事件掩码或文件 Descriptors 无效的情况下引发ValueError,或者在未注册文件对象的情况下返回KeyError

如果timeout > 0,则指定最大 await 时间,以秒为单位。如果timeout <= 0,则该调用将不会阻塞,并且将报告当前准备就绪的文件对象。如果* timeout *为None,则调用将阻塞,直到被监视的文件对象准备就绪为止。

这将返回一个(key, events)Tuples 的列表,每个就绪文件对象一个。

Note

如果当前进程收到 signal,则该方法可以在任何文件对象准备就绪或超时之前返回:在这种情况下,将返回一个空列表。

在版本 3.5 中进行了更改:现在,如果 signal 处理程序没有引发异常(请参阅 PEP 475),则被 signal break时,selectors 将被 signal break,并重新计算超时,而不是在超时之前返回空事件列表。

必须调用它以确保释放任何基础资源。selectors 一旦关闭就不得使用。

这将返回与此文件对象关联的SelectorKey实例,如果未注册文件对象,则返回KeyError

这将返回一个Mapping实例,该实例将注册的文件对象 Map 到其关联的SelectorKey实例。

3.5 版中的新Function。

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)
首页