select — Ожидание завершения ввода-вывода


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

Примечание

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

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

exception select.error

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

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

select.devpoll()

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

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

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

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

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

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

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

sizehint информирует epoll об ожидаемом количестве регистрируемых событий. Он должен быть положительным или -1, чтобы использовать значение по умолчанию. Он используется только в старых системах, где epoll_create1() недоступен; в противном случае он не действует (хотя его значение все равно проверяется).

flags устарел и полностью игнорируется. Однако при подаче его значение должно быть 0 или select.EPOLL_CLOEXEC, в противном случае вызывается OSError.

См. раздел Объекты epoll далее, чтобы узнать о методах, поддерживаемых объектами epolling.

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

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

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

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

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

select.poll()

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

select.kqueue()

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

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

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

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

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

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

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

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

Пустые итерации разрешены, но принятие трёх пустых итераций зависит от платформы. (Известно, что она работает в 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.

Объекты опроса /dev/poll

У Solaris и производных есть /dev/poll. В то время как select() — это O(самый высокий файловый дескриптор), а poll() — O(количество файловых дескрипторов), /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])

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

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

Объекты epoll

Man страница по epoll.

eventmask

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

Добавлено в версии 3.6: Добавлен EPOLLEXCLUSIVE. Он поддерживается только ядром Linux 4.5 или более поздней версии.

epoll.close()

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

epoll.closed

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

epoll.fileno()

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

epoll.fromfd(fd)

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

epoll.register(fd[, eventmask])

Регистрирует дескриптор fd с объектом epoll.

epoll.modify(fd, eventmask)

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

epoll.unregister(fd)

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

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

Ожидает событий. Тайм-аут в секундах (с плавающей запятой).

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

Polling объекты

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

poll.register(fd[, eventmask])

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

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

Константа Значение
POLLIN Есть данные для чтения
POLLPRI Есть срочные данные для чтения
POLLOUT Готов к выводу: запись не блокируется
POLLERR Состояние какой-то ошибки
POLLHUP Повесить трубку
POLLRDHUP Потоковый сокет однорангового соединения закрывается или завершение записи на половине соединения.
POLLNVAL Недопустимый запрос: дескриптор не открыт

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

poll.modify(fd, eventmask)

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

poll.unregister(fd)

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

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

poll.poll([timeout])

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

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

Объекты kqueue

kqueue.close()

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

kqueue.closed

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

kqueue.fileno()

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

kqueue.fromfd(fd)

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

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

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

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

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

Объекты kevent

Man страница по kevent

kevent.ident

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

kevent.filter

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

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

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

Константа Значение
KQ_EV_ADD Добавление или изменение события
KQ_EV_DELETE Удаляет событие из очереди
KQ_EV_ENABLE Permitscontrol() для возвращаемого события
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

Пользовательское значение.