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

18.3. select – Ожидание завершения ввода/выводаselect – Waiting for I/O completion


Этот модуль предоставляет доступ к функциям select() и poll(), доступным в большинстве операционных систем, devpoll() – на Solaris и производных, epoll() – на Linux 2.5+ и kqueue() – на большинстве BSD. Обратите внимание: в Windows он работает только с сокетами; в других ОС он также работает с другими типами файлов (в частности, в Unix – с каналами). Его нельзя использовать для обычных файлов, чтобы определить, увеличился ли файл с момента последнего чтения.

Примечание

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

Модуль определяет следующее:

exception select.error

Устаревший псевдоним OSError.

Изменено в версии 3.3: В соответствии с PEP 3151 этот класс стал псевдонимом OSError.

select.devpoll()

Поддерживается только на Solaris и производных. Возвращает объект /dev/poll опроса; см. раздел /dev/poll Polling Objects ниже для методов, поддерживаемых объектами devpoll.

Объекты devpoll() привязаны к количеству файловых дескрипторов, разрешённых на момент создания. Если программа уменьшает это значение, devpoll() завершится ошибкой. Если программа увеличивает это значение, devpoll() может вернуть неполный список активных файловых дескрипторов.

Новый файловый дескриптор является ненаследуемым.

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

Изменено в версии 3.4: Новый файловый дескриптор теперь не наследуется.

select.epoll(sizehint=-1, flags=0)

Поддерживается только на Linux версии 2.5.44 и новее. Возвращает объект опроса по фронту, который можно использовать как интерфейс со срабатыванием по фронту или по уровню для событий ввода/вывода. sizehint и flags устарели и полностью игнорируются.

См. раздел Edge and Level Trigger Polling (epoll) Objects ниже для методов, поддерживаемых объектами epoll.

Объекты epoll поддерживают протокол менеджера контекста: при использовании в инструкции with новый файловый дескриптор автоматически закрывается в конце блока.

Новый файловый дескриптор является ненаследуемым.

Изменено в версии 3.3: Добавлен параметр flags.

Изменено в версии 3.4: Добавлена поддержка инструкции with. Теперь новый файловый дескриптор является ненаследуемым.

Устарело с версии 3.4: Параметр flags. Теперь по умолчанию используется select.EPOLL_CLOEXEC. Используйте os.set_inheritable(), чтобы сделать файловый дескриптор наследуемым.

select.poll()

Поддерживается не всеми операционными системами. Возвращает объект опроса, который поддерживает регистрацию и отмену регистрации файловых дескрипторов, а затем опрос их на предмет событий ввода-вывода; см. раздел Polling Objects ниже для методов, поддерживаемых объектами опроса.

select.kqueue()

Поддерживается только на BSD. Возвращает объект очереди ядра; см. раздел Kqueue Objects ниже для методов, поддерживаемых объектами kqueue.

Новый файловый дескриптор является ненаследуемым.

Изменено в версии 3.4: Новый файловый дескриптор теперь не наследуется.

select.kevent(ident, filter=KQ_FILTER_READ, flags=KQ_EV_ADD, fflags=0, data=0, udata=0)

Поддерживается только на BSD. Возвращает объект события ядра; см. раздел Kevent Objects ниже для методов, поддерживаемых объектами kevent.

select.select(rlist, wlist, xlist[, timeout])

Это простой интерфейс к системному вызову select() Unix. Первые три аргумента – последовательности «ожидаемых объектов»: целые числа, представляющие файловые дескрипторы, или объекты с методом без параметров fileno(), возвращающим такое целое число:

  • rlist: ожидать готовности к чтению
  • wlist: ожидать готовности к записи
  • xlist: ожидать «исключительного условия» (см. справочную страницу для того, что ваша система считает таким условием)

Пустые последовательности допускаются, но поддержка трёх пустых последовательностей зависит от платформы. (Известно, что это работает в Unix, но не в Windows.) Необязательный аргумент timeout задаёт тайм-аут в секундах как число с плавающей запятой. Если аргумент timeout опущен, функция блокируется, пока хотя бы один файловый дескриптор не будет готов. Нулевой тайм-аут соответствует опросу, без блокировки.

Возвращаемое значение – тройка списков готовых объектов: подмножества первых трех аргументов. Когда тайм-аут истекает без готовности файлового дескриптора, возвращаются три пустых списка.

Среди допустимых типов объектов в последовательностях – файловые объекты Python (например, sys.stdin или объекты, возвращаемые open() или os.popen()), сокеты, возвращаемые socket.socket(). Можно также определить собственный класс-обёртку, если у него есть соответствующий метод fileno() (который действительно возвращает файловый дескриптор, а не просто произвольное целое число).

Примечание

Файловые объекты в Windows недопустимы, но сокеты – да. В Windows базовая функция select() предоставляется библиотекой WinSock и не обрабатывает файловые дескрипторы, не происходящие из WinSock.

Изменено в версии 3.5: Функция теперь повторяется с пересчитанным тайм-аутом при прерывании сигналом, за исключением случая, когда обработчик сигнала вызывает исключение (см. PEP 475 для обоснования), вместо вызова InterruptedError.

select.PIPE_BUF

Минимальное количество байт, которое можно записать в канал без блокировки, когда канал сообщён как готовый к записи с помощью select(), poll() или другого интерфейса в этом модуле. Это не относится к другим файлоподобным объектам, таким как сокеты.

Это значение гарантируется POSIX как минимум 512. Доступность: Unix.

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

18.3.1. /dev/poll Объекты опроса/dev/poll Polling Objects

Solaris и их производные имеют /dev/poll. В то время как select() работает за O(наибольший файловый дескриптор), а poll() – за O(количество файловых dескрипторов), /dev/poll работает за O(активные файловые дескрипторы).

Поведение /dev/poll очень близко к стандартному объекту poll().

devpoll.close()

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

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

devpoll.closed

True если объект опроса закрыт.

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

devpoll.fileno()

Возвращает номер файлового дескриптора объекта опроса.

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

devpoll.register(fd[, eventmask])

Регистрирует файловый дескриптор в объекте опроса. Последующие вызовы метода poll() будут проверять, есть ли у файлового дескриптора ожидающие события ввода-вывода. fd может быть целым числом или объектом с методом fileno(), возвращающим целое число. Файловые объекты реализуют fileno(), поэтому их тоже можно использовать в качестве аргумента.

eventmask – необязательная битовая маска, описывающая тип событий для проверки. Константы те же, что и у объекта poll(). Значение по умолчанию – комбинация констант POLLIN, POLLPRI и POLLOUT.

Предупреждение

Регистрация уже зарегистрированного файлового дескриптора не является ошибкой, но результат не определен. Правильным действием будет сначала отменить регистрацию или изменить его. Это важное отличие от poll().

devpoll.modify(fd[, eventmask])

Этот метод выполняет unregister(), а затем register(). Это (немного) эффективнее, чем делать то же самое явно.

devpoll.unregister(fd)

Удаляет файловый дескриптор, отслеживаемый объектом опроса. Как и метод register(), fd может быть целым числом или объектом с методом fileno(), возвращающим целое число.

Попытка удалить файловый дескриптор, который никогда не был зарегистрирован, безопасно игнорируется.

devpoll.poll([timeout])

Опрашивает набор зарегистрированных файловых дескрипторов и возвращает, возможно, пустой список, содержащий кортежи (fd, event) из двух элементов для дескрипторов, по которым есть события или ошибки. fd – это файловый дескриптор, а event – битовая маска, в которой установлены биты для сообщённых событий этого дескриптора: POLLIN для ожидания ввода, POLLOUT указывает, что дескриптор можно записывать, и так далее. Пустой список означает, что вызов завершился по таймауту и ни один файловый дескриптор не сообщил о событиях. Если задан timeout, он задаёт время в миллисекундах, в течение которого система будет ждать события перед возвратом. Если timeout опущен, равен -1 или None, вызов будет блокироваться до появления события для этого объекта poll.

Изменено в версии 3.5: Функция теперь повторяется с пересчитанным тайм-аутом при прерывании сигналом, за исключением случая, когда обработчик сигнала вызывает исключение (см. PEP 475 для обоснования), вместо вызова InterruptedError.

18.3.2. Edge и Level Trigger Polling (epoll) объектыEdge and Level Trigger Polling (epoll) Objects

http://linux.die.net/man/4/epoll

eventmask

Константа Значение
EPOLLIN Доступен для чтения
EPOLLOUT Доступен для записи
EPOLLPRI Срочные данные для чтения
EPOLLERR Возникла ошибка на ассоциированном файловом дескрипторе
EPOLLHUP Произошёл разрыв соединения на ассоциированном файловом дескрипторе
EPOLLET Установить триггер по фронту (Edge Trigger), по умолчанию – триггер по уровню (Level Trigger)
EPOLLONESHOT Установить одноразовое поведение. После извлечения одного события файловый дескриптор внутренне отключается.
EPOLLRDNORM Эквивалентно EPOLLIN
EPOLLRDBAND Полоса приоритетных данных доступна для чтения.
EPOLLWRNORM Эквивалентно EPOLLOUT
EPOLLWRBAND Приоритетные данные могут быть записаны.
EPOLLMSG Игнорируется.
epoll.close()

Закрывает управляющий файловый дескриптор объекта epoll.

epoll.closed

True, если объект epoll закрыт.

epoll.fileno()

Возвращает номер файлового дескриптора управляющего fd.

epoll.fromfd(fd)

Создает объект epoll из заданного файлового дескриптора.

epoll.register(fd[, eventmask])

Регистрирует файловый дескриптор в объекте epoll.

epoll.modify(fd, eventmask)

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

epoll.unregister(fd)

Удаляет зарегистрированный файловый дескриптор из объекта epoll.

epoll.poll(timeout=-1, maxevents=-1)

Ожидает события. timeout в секундах (float)

Изменено в версии 3.5: Функция теперь повторяется с пересчитанным тайм-аутом при прерывании сигналом, за исключением случая, когда обработчик сигнала вызывает исключение (см. PEP 475 для обоснования), вместо вызова InterruptedError.

18.3.3. Объекты опросаPolling Objects

Системный вызов poll(), поддерживаемый в большинстве Unix-систем, обеспечивает лучшую масштабируемость для сетевых серверов, обслуживающих множество клиентов одновременно. poll() масштабируется лучше, поскольку системный вызов требует только перечисления интересующих файловых дескрипторов, тогда как select() строит битовую маску, устанавливает биты для нужных файловых дескрипторов, а затем всю битовую маску приходится снова линейно сканировать. select() имеет сложность O(наибольший файловый дескриптор), а poll() – O(количество файловых дескрипторов).

poll.register(fd[, eventmask])

Регистрирует файловый дескриптор в объекте опроса. Последующие вызовы метода poll() будут проверять, есть ли у файлового дескриптора ожидающие события ввода-вывода. fd может быть целым числом или объектом с методом fileno(), возвращающим целое число. Файловые объекты реализуют fileno(), поэтому их тоже можно использовать в качестве аргумента.

eventmask – необязательная битовая маска, описывающая типы событий для проверки. Может быть комбинацией констант POLLIN, POLLPRI и POLLOUT, описанных в таблице ниже. Если не указана, по умолчанию проверяются все три типа событий.

Константа Значение
POLLIN Есть данные для чтения
POLLPRI Есть срочные данные для чтения
POLLOUT Готов к выводу: запись не будет блокироваться
POLLERR Условие ошибки (какого-либо рода)
POLLHUP Разъединение
POLLNVAL Некорректный запрос: дескриптор не открыт

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

poll.modify(fd, eventmask)

Изменяет уже зарегистрированный fd. Это имеет тот же эффект, что и register(fd, eventmask). Попытка изменить файловый дескриптор, который никогда не был зарегистрирован, приводит к возбуждению исключения OSError с errno ENOENT.

poll.unregister(fd)

Удаляет файловый дескриптор, отслеживаемый объектом опроса. Как и метод register(), fd может быть целым числом или объектом с методом fileno(), возвращающим целое число.

Попытка удалить файловый дескриптор, который никогда не был зарегистрирован, приводит к возбуждению исключения KeyError.

poll.poll([timeout])

Опрашивает набор зарегистрированных файловых дескрипторов и возвращает, возможно, пустой список, содержащий кортежи (fd, event) из двух элементов для дескрипторов, по которым есть события или ошибки. fd – это файловый дескриптор, а event – битовая маска, в которой установлены биты для сообщённых событий этого дескриптора: POLLIN для ожидания ввода, POLLOUT указывает, что дескриптор можно записывать, и так далее. Пустой список означает, что вызов завершился по таймауту и ни один файловый дескриптор не сообщил о событиях. Если задан timeout, он задаёт время в миллисекундах, в течение которого система будет ждать события перед возвратом. Если timeout опущен, отрицателен или равен None, вызов будет блокироваться до появления события для этого объекта poll.

Изменено в версии 3.5: Функция теперь повторяется с пересчитанным тайм-аутом при прерывании сигналом, за исключением случая, когда обработчик сигнала вызывает исключение (см. PEP 475 для обоснования), вместо вызова InterruptedError.

18.3.4. Объекты kqueueKqueue Objects

kqueue.close()

Закрывает файловый дескриптор управления объекта kqueue.

kqueue.closed

True, если объект kqueue закрыт.

kqueue.fileno()

Возвращает номер файлового дескриптора управляющего fd.

kqueue.fromfd(fd)

Создаёт объект kqueue из заданного файлового дескриптора.

kqueue.control(changelist, max_events[, timeout=None]) → eventlist

Низкоуровневый интерфейс к kevent

  • changelist должен быть итерируемым объектом kevent или None
  • max_events должен быть 0 или положительным целым числом
  • тайм-аут в секундах (возможны числа с плавающей запятой)

Изменено в версии 3.5: Функция теперь повторяется с пересчитанным тайм-аутом при прерывании сигналом, за исключением случая, когда обработчик сигнала вызывает исключение (см. PEP 475 для обоснования), вместо вызова InterruptedError.

18.3.5. Объекты keventKevent Objects

https://www.freebsd.org/cgi/man.cgi?query=kqueue&sektion=2

kevent.ident

Значение, используемое для идентификации события. Интерпретация зависит от фильтра, но обычно это файловый дескриптор. В конструкторе ident может быть либо целым числом, либо объектом с методом fileno(). kevent хранит целое число внутри.

kevent.filter

Имя фильтра ядра.

Константа Значение
KQ_FILTER_READ Принимает дескриптор и возвращает управление при появлении данных, доступных для чтения
KQ_FILTER_WRITE Принимает дескриптор и возвращает управление при появлении возможности записи
KQ_FILTER_AIO Запросы AIO
KQ_FILTER_VNODE Возвращает управление при наступлении одного или нескольких запрошенных событий, за которыми ведется наблюдение в fflag
KQ_FILTER_PROC Отслеживание событий по идентификатору процесса
KQ_FILTER_NETDEV Отслеживание событий на сетевом устройстве [недоступно в Mac OS X]
KQ_FILTER_SIGNAL Возвращает управление при доставке отслеживаемого сигнала процессу
KQ_FILTER_TIMER Устанавливает произвольный таймер
kevent.flags

Действие фильтра.

Константа Значение
KQ_EV_ADD Добавляет или изменяет событие
KQ_EV_DELETE Удаляет событие из очереди
KQ_EV_ENABLE Позволяет control() вернуть событие
KQ_EV_DISABLE Отключает событие
KQ_EV_ONESHOT Удаляет событие после первого срабатывания
KQ_EV_CLEAR Сбрасывает состояние после извлечения события
KQ_EV_SYSFLAGS внутреннее событие
KQ_EV_FLAG1 внутреннее событие
KQ_EV_EOF Условие EOF для конкретного фильтра
KQ_EV_ERROR См. возвращаемые значения
kevent.fflags

Флаги, специфичные для фильтра

KQ_FILTER_READ и KQ_FILTER_WRITE флаги фильтра:

Константа Значение
KQ_NOTE_LOWAT нижняя граница буфера сокета

KQ_FILTER_VNODE флаги фильтра:

Константа Значение
KQ_NOTE_DELETE была вызвана unlink()
KQ_NOTE_WRITE произошла запись
KQ_NOTE_EXTEND файл был расширен
KQ_NOTE_ATTRIB атрибут был изменён
KQ_NOTE_LINK количество ссылок изменилось
KQ_NOTE_RENAME файл был переименован
KQ_NOTE_REVOKE доступ к файлу был отозван

KQ_FILTER_PROC флаги фильтра:

Константа Значение
KQ_NOTE_EXIT процесс завершился
KQ_NOTE_FORK процесс вызвал fork()
KQ_NOTE_EXEC процесс запустил новый процесс
KQ_NOTE_PCTRLMASK внутренний флаг фильтра
KQ_NOTE_PDATAMASK внутренний флаг фильтра
KQ_NOTE_TRACK отслеживать процесс через fork()
KQ_NOTE_CHILD возвращено в дочернем процессе для NOTE_TRACK
KQ_NOTE_TRACKERR не удаётся подключиться к дочернему процессу

KQ_FILTER_NETDEV флаги фильтра (недоступно в Mac OS X):

Константа Значение
KQ_NOTE_LINKUP соединение активно
KQ_NOTE_LINKDOWN соединение разорвано
KQ_NOTE_LINKINV состояние соединения недействительно
kevent.data

Данные, специфичные для фильтра.

kevent.udata

Значение, определённое пользователем.