Документация Python неофициальный перевод
Содержание страницы

18.4. selectors – Высокоуровневая мультиплексация ввода-выводаselectors – High-level I/O multiplexing

Новое в версии 3.4.

18.4.1. ВведениеIntroduction

Этот модуль предоставляет высокоуровневую и эффективную мультиплексацию ввода-вывода, построенную на примитивах модуля select. Пользователям рекомендуется использовать именно этот модуль, если только они не хотят точного контроля над используемыми примитивами уровня ОС.

В нём определяется абстрактный базовый класс BaseSelector, а также несколько конкретных реализаций (KqueueSelector, EpollSelector...), которые можно использовать для ожидания уведомлений о готовности ввода-вывода для нескольких файловых объектов. В дальнейшем под «файловым объектом» понимается любой объект с методом fileno() или целочисленный файловый дескриптор. См. file object.

DefaultSelector – это псевдоним наиболее эффективной реализации, доступной на текущей платформе; это должен быть выбор по умолчанию для большинства пользователей.

Примечание

Тип поддерживаемых файловых объектов зависит от платформы: в Windows поддерживаются сокеты, но не каналы, тогда как в Unix поддерживаются и сокеты, и каналы (также могут поддерживаться и другие типы, например именованные каналы или специальные файловые устройства).

См. также

select
Модуль низкоуровневого мультиплексирования ввода-вывода.

18.4.2. КлассыClasses

Иерархия классов:

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

В дальнейшем events – это битовая маска, указывающая, какие события ввода-вывода следует ожидать для данного файлового объекта. Она может быть комбинацией следующих констант:

Константа Значение
EVENT_READ Доступен для чтения
EVENT_WRITE Доступен для записи
class selectors.SelectorKey

SelectorKey – это namedtuple, используемый для связи файлового объекта с его базовым файловым дескриптором, выбранной маской событий и прикреплёнными данными. Он возвращается несколькими методами BaseSelector.

fileobj

Зарегистрированный файловый объект.

fd

Нижележащий файловый дескриптор.

events

События, которые необходимо ожидать для этого файлового объекта.

data

Необязательные непрозрачные данные, связанные с этим файловым объектом: например, их можно использовать для хранения идентификатора сессии для каждого клиента.

class selectors.BaseSelector

BaseSelector используется для ожидания готовности событий ввода-вывода на нескольких файловых объектах. Он поддерживает регистрацию и отмену регистрации файловых потоков, а также метод для ожидания событий ввода-вывода на этих потоках с необязательным тайм-аутом. Это абстрактный базовый класс, поэтому его нельзя инстанциировать. Используйте DefaultSelector или один из SelectSelector, KqueueSelector и т. д., если вы хотите использовать конкретную реализацию, и ваша платформа её поддерживает. BaseSelector и его конкретные реализации поддерживают протокол менеджера контекста.

register(fileobj, events, data=None)

Регистрирует файловый объект для выбора, отслеживая события ввода-вывода.

fileobj – это файловый объект для наблюдения. Он может быть целочисленным файловым дескриптором или объектом с методом fileno(). events – битовая маска событий для наблюдения. data – непрозрачный объект.

Возвращает новый экземпляр SelectorKey или вызывает ValueError в случае недопустимой маски событий или файлового дескриптора, или KeyError, если файловый объект уже зарегистрирован.

unregister(fileobj)

Отменяет регистрацию файлового объекта, удаляя его из отслеживания. Файловый объект должен быть отменён до закрытия.

fileobj должен быть ранее зарегистрированным файловым объектом.

Возвращает соответствующий экземпляр SelectorKey или вызывает KeyError, если fileobj не зарегистрирован. Также вызовет ValueError, если fileobj недопустим (например, у него нет метода fileno() или его метод fileno() возвращает недопустимое значение).

modify(fileobj, events, data=None)

Изменяет отслеживаемые события или присоединённые данные зарегистрированного файлового объекта.

Это эквивалентно вызову BaseSelector.unregister(fileobj)() с последующим BaseSelector.register(fileobj, events, data)(), за исключением того, что это может быть реализовано более эффективно.

Возвращает новый экземпляр SelectorKey или вызывает ValueError в случае недопустимой маски событий или файлового дескриптора, или KeyError, если файловый объект не зарегистрирован.

select(timeout=None)

Ожидает, пока некоторые зарегистрированные файловые объекты не станут готовы, или пока не истечёт тайм-аут.

Если timeout > 0, это задаёт максимальное время ожидания в секундах. Если timeout <= 0, вызов не будет блокироваться и сообщит о текущих готовых файловых объектах. Если timeout равен None, вызов будет блокироваться, пока контролируемый файловый объект не станет готов.

Возвращает список кортежей (key, events) по одному для каждого готового файлового объекта.

key – это экземпляр SelectorKey, соответствующий готовому файловому объекту. events – битовая маска событий, готовых на этом файловом объекте.

Примечание

Этот метод может вернуть результат до того, как какой-либо файловый объект станет готовым или истечёт тайм-аут, если текущий процесс получает сигнал: в этом случае будет возвращён пустой список.

close()

Закрывает селектор.

Должен быть вызван, чтобы гарантировать освобождение всех базовых ресурсов. Селектор нельзя использовать после его закрытия.

get_key(fileobj)

Возвращает ключ, связанный с зарегистрированным файловым объектом.

Возвращает экземпляр SelectorKey, связанный с этим файловым объектом, или вызывает KeyError, если файловый объект не зарегистрирован.

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.KqueueSelector

Селектор на основе select.kqueue().

fileno()

Возвращает файловый дескриптор, используемый нижележащим объектом select.kqueue().

18.4.3. ПримерыExamples

Ниже приведена простая реализация эхо-сервера:

import selectors
import socket

sel = selectors.DefaultSelector()

def accept(sock, mask):
    conn, addr = sock.accept()  # Должен быть готов
    print('accepted', conn, 'from', addr)
    conn.setblocking(False)
    sel.register(conn, selectors.EVENT_READ, read)

def read(conn, mask):
    data = conn.recv(1000)  # Должен быть готов
    if data:
        print('echoing', repr(data), 'to', conn)
        conn.send(data)  # Надеюсь, не заблокируется
    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)