selectors — Высокоуровневое мультиплексирование ввода-вывода

Добавлено в версии 3.4.


Вступление

Данный модуль обеспечивает высокоуровневое и эффективное мультиплексирование ввода-вывода, основанное на примитивах модуля select. Вместо этого пользователям рекомендуется использовать данный модуль, если они не хотят точного контроля над используемыми примитивами уровня ОС.

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

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

Примечание

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

См.также

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

Классы

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

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

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

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

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

fileobj

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

fd

Базовый файловый дескриптор.

events

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

data

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

class selectors.BaseSelector

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

abstractmethod register(fileobj, events, data=None)

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

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

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

abstractmethod unregister(fileobj)

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

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

Возвращает связанный экземпляр SelectorKey или вызывает KeyError, если fileobj не зарегистрирован. Он поднимет ValueError, если fileobj недействителен (например, у него нет метода 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), по одному для каждого готового файлового объекта.

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

Примечание

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

Изменено в версии 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().

Примеры

Вот простая реализация эхо-сервера:

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)