selectors ---高电平I/O多路复用

3.4 新版功能.

源代码: Lib/selectors.py


介绍

该模块允许在 select 模块原语。鼓励用户使用此模块,除非他们希望对所使用的操作系统级原语进行精确控制。

它定义了 BaseSelector 抽象基类,以及一些具体的实现 (KqueueSelectorEpollSelector …),可用于等待多个文件对象上的I/O就绪通知。在以下内容中,“文件对象”是指具有 fileno() 方法或原始文件描述符。见 file object .

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

注解

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

参见

select

低电平I/O多路复用模块。

Classes

类层次结构:

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

在以下内容中, 事件 是一个位掩码,指示在给定的文件对象上应等待哪些I/O事件。它可以是以下模块常量的组合:

常数

意义

EVENT_READ

可供阅读

EVENT_WRITE

可供写入

class selectors.SelectorKey

A SelectorKey 是一个 namedtuple 用于将文件对象与其基础文件描述符、所选事件掩码和附加数据关联。它被几个人送回 BaseSelector 方法。

fileobj

文件对象已注册。

fd

基础文件描述符。

events

必须在此文件对象上等待的事件。

data

与此文件对象关联的可选不透明数据:例如,它可以用于存储每个客户端会话ID。

class selectors.BaseSelector

A BaseSelector 用于等待多个文件对象的I/O事件就绪。它支持文件流注册、注销和等待这些流上I/O事件的方法,并具有可选的超时。它是抽象基类,因此无法实例化。使用 DefaultSelector 相反,或者 SelectSelectorKqueueSelector 等等。如果您想专门使用一个实现,并且您的平台支持它。 BaseSelector 它的具体实现支持 context manager 协议。

abstractmethod register(fileobj, events, data=None)

注册一个文件对象进行选择,监视它的I/O事件。

文件对象 是要监视的文件对象。它可以是整数文件描述符,也可以是具有 fileno() 方法。 事件 是要监视的事件的按位掩码。 data 是一个不透明的对象。

这将返回一个新的 SelectorKey 实例,或引发 ValueError 如果事件掩码或文件描述符无效,或 KeyError 如果文件对象已注册。

abstractmethod unregister(fileobj)

从选择中注销文件对象,从监视中删除它。档案标的在关闭前应当注销。

文件对象 必须是以前注册的文件对象。

这将返回关联的 SelectorKey 实例,或引发 KeyError 如果 文件对象 未注册。它会升起 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 ,调用不会阻塞,并将报告当前就绪的文件对象。如果 timeoutNone ,调用将被阻止,直到被监视的文件对象准备就绪。

这将返回 (key, events) 元组,每个就绪文件对象一个。

keySelectorKey 对应于就绪文件对象的实例。 事件 事件的位掩码是否在此文件对象上就绪。

注解

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

在 3.5 版更改: 如果信号处理程序没有引发异常,则当被信号中断时,选择器将以重新计算的超时重试(请参见 PEP 475 而不是返回超时前事件的空列表。

close()

关闭选择器。

必须调用此函数以确保释放任何基础资源。选择器关闭后不得使用。

get_key(fileobj)

返回与已注册文件对象关联的键。

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

abstractmethod get_map()

返回文件对象到选择器键的映射。

返回一个 Mapping 实例将已注册的文件对象映射到其关联的 SelectorKey 实例。

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() 对象。

实例

下面是一个简单的echo服务器实现:

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)