Spec-Zone.ru › Python 3.5

signal — Установка обработчиков асинхронных событий

Этот модуль предоставляет механизмы использования обработчиков сигналов в Python.

1. Общие правила

Функция signal.signal() позволяет определить пользовательские обработчики, которые будут выполнены при получении сигнала. Несколько обработчиков по умолчанию установлены: SIGPIPE игнорируется (чтобы ошибки записи в каналы и сокеты могли быть сообщены как обычные исключения Python) и SIGINT преобразуется в исключение KeyboardInterrupt.

Обработчик для конкретного сигнала, после установки, остается установленным до его явного сброса (Python эмулирует интерфейс в стиле BSD независимо от реализации), за исключением обработчика для SIGCHLD, который следует реализации.

1.1. Выполнение обработчиков сигналов Python

Обработчик сигнала Python не выполняется внутри низкоуровневого (C) обработчика сигнала. Вместо этого низкоуровневый обработчик сигнала устанавливает флаг, который сообщает виртуальной машине Python выполнить соответствующий обработчик сигнала Python в более поздний момент (например, в следующей инструкции байткода). Это имеет последствия:

  • Это мало имеет смысла для перехвата синхронных ошибок, таких как SIGFPE или SIGSEGV, которые вызваны некорректной операцией в коде C. Python вернется из обработчика сигнала в код C, который, вероятно, снова сгенерирует тот же сигнал, что приведет к тому, что Python, по-видимому, зависнет. Начиная с Python 3.3, вы можете использовать модуль faulthandler для отчета о синхронных ошибках.
  • Длительное вычисление, реализованное только на C (например, сопоставление регулярных выражений с большим объемом текста), может выполняться непрерывно в течение произвольного времени, независимо от полученных сигналов. Обработчики сигналов Python будут вызваны после завершения вычисления.

1.2. Сигналы и потоки

Обработчики сигналов Python всегда выполняются в основном потоке Python, даже если сигнал был получен в другом потоке. Это означает, что сигналы не могут использоваться в качестве средства межпотоковой связи. Вместо этого вы можете использовать примитивы синхронизации из модуля threading.

Кроме того, только основной поток может установить новый обработчик сигнала.

2. Содержимое модуля

Изменено в версии 3.5: сигналы (SIG*), обработчики (SIG_DFL, SIG_IGN) и sigmask (SIG_BLOCK, SIG_UNBLOCK, SIG_SETMASK) связанные константы, перечисленные ниже, были преобразованы в enums. getsignal(), pthread_sigmask(), sigpending() и sigwait() функции возвращают удобочитаемые enums.

Переменные, определенные в модуле signal:

signal.SIG_DFL

Это один из двух стандартных вариантов обработки сигналов; он просто выполнит функцию по умолчанию для сигнала. Например, на большинстве систем по умолчанию для SIGQUIT — это вывести дамп ядра и выйти, а по умолчанию для SIGCHLD — просто игнорировать его.

signal.SIG_IGN

Это другой стандартный обработчик сигнала, который просто проигнорирует данный сигнал.

SIG*

Все номера сигналов определены символически. Например, сигнал завершения сеанса определяется как signal.SIGHUP; имена переменных идентичны именам, используемым в программах C, как указано в <signal.h>. Справочная страница Unix для ‘signal()’ перечисляет существующие сигналы (на некоторых системах это signal(2), на других список находится в signal(7)). Обратите внимание, что не все системы определяют один и тот же набор имён сигналов; только те имена, которые определены системой, определяются этим модулем.

signal.CTRL_C_EVENT

Сигнал, соответствующий событию нажатия клавиш Ctrl+C. Этот сигнал может использоваться только с os.kill().

Доступность: Windows.

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

signal.CTRL_BREAK_EVENT

Сигнал, соответствующий событию нажатия клавиш Ctrl+Break. Этот сигнал может использоваться только с os.kill().

Доступность: Windows.

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

signal.NSIG

На единицу больше, чем номер самого высокого номера сигнала.

signal.ITIMER_REAL

Уменьшает таймер интервалов в реальном времени и отправляет SIGALRM при истечении срока действия.

signal.ITIMER_VIRTUAL

Уменьшает таймер интервалов только при выполнении процесса и отправляет SIGVTALRM при истечении срока действия.

signal.ITIMER_PROF

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

signal.SIG_BLOCK

Возможная величина для параметра how функции pthread_sigmask(), указывающая на то, что сигналы должны быть заблокированы.

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

signal.SIG_UNBLOCK

Возможная величина для параметра how функции pthread_sigmask(), указывающая на то, что сигналы должны быть разблокированы.

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

signal.SIG_SETMASK

Возможная величина для параметра how функции pthread_sigmask(), указывающая на то, что маска сигналов должна быть заменена.

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

Модуль signal определяет одно исключение:

exception signal.ItimerError

Выбрасывается для сигнализации об ошибке из реализации setitimer() или getitimer(). Ожидайте эту ошибку, если в setitimer() передается некорректный таймер интервала или отрицательное время. Эта ошибка является подтипом OSError.

Добавлен в версии 3.3: Эта ошибка раньше была подтипом IOError, который теперь является псевдонимом OSError.

Модуль signal определяет следующие функции:

signal.alarm(time)

Если time не равно нулю, эта функция запрашивает отправку сигнала SIGALRM процессу через time секунд. Любой ранее запланированный сигнал тревоги отменяется (может быть запланирован только один сигнал тревоги). Возвращаемое значение — количество секунд до того, как был отправлен любой ранее заданный сигнал тревоги. Если time равно нулю, сигнал тревоги не планируется, а запланированный сигнал тревоги отменяется. Если возвращаемое значение равно нулю, в настоящее время сигнал тревоги не запланирован. (См. страницу справки Unix alarm(2)). Доступность: Unix.

END_OF_DOCUMENT_MARKER
signal.getsignal(signalnum)

Возвращает текущий обработчик сигнала для сигнала signalnum. Возвращаемое значение может быть вызываемым объектом Python или одним из специальных значений signal.SIG_IGN, signal.SIG_DFL или None. Здесь, signal.SIG_IGN означает, что сигнал ранее игнорировался, signal.SIG_DFL означает, что ранее использовался стандартный способ обработки сигнала, а None означает, что предыдущий обработчик сигнала не был установлен из Python.

signal.pause()

Приводит процесс к состоянию ожидания до получения сигнала; затем будет вызван соответствующий обработчик. Ничего не возвращает. Не работает в Windows. (См. страницу справки Unix signal(2).)

См. также sigwait(), sigwaitinfo(), sigtimedwait() и sigpending().

signal.pthread_kill(thread_id, signalnum)

Отправляет сигнал signalnum потоку thread_id, другому потоку в том же процессе, что и вызывающий поток. Целевой поток может выполнять любой код (Python или нет). Однако, если целевой поток выполняет интерпретатор Python, обработчики сигналов Python будут выполнены главным потоком. Поэтому единственная причина отправки сигнала конкретному потоку Python — заставить выполняемый системный вызов завершиться ошибкой с помощью InterruptedError.

Используйте threading.get_ident() или атрибут ident объектов threading.Thread, чтобы получить подходящее значение для thread_id.

Если signalnum равно 0, то сигнал не отправляется, но проверка ошибок всё равно выполняется; это можно использовать для проверки, всё ли ещё работает целевой поток.

Доступность: Unix (см. страницу справки pthread_kill(3) для дополнительной информации).

См. также os.kill().

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

signal.pthread_sigmask(how, mask)

Извлечение и/или изменение маски сигналов вызывающего потока. Маска сигналов — это набор сигналов, доставка которых в данный момент заблокирована для вызывающего потока. Возвращает старую маску сигналов в виде набора сигналов.

Поведение вызова зависит от значения how, как показано ниже.

  • SIG_BLOCK: Набор заблокированных сигналов — объединение текущего набора и аргумента mask.
  • SIG_UNBLOCK: Сигналы в mask удаляются из текущего набора заблокированных сигналов. Разрешено пытаться разблокировать сигнал, который не заблокирован.
  • SIG_SETMASK: Набор заблокированных сигналов устанавливается в значение аргумента mask.

mask — это набор номеров сигналов (например, {signal.SIGINT, signal.SIGTERM}). Используйте range(1, signal.NSIG) для полной маски, включающей все сигналы.

Например, signal.pthread_sigmask(signal.SIG_BLOCK, []) считывает маску сигналов вызывающего потока.

Доступность: Unix. См. страницу справки sigprocmask(3) и pthread_sigmask(3) для дополнительной информации.

См. также pause(), sigpending() и sigwait().

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

signal.setitimer(which, seconds[, interval])

Устанавливает заданный таймер интервалов (один из signal.ITIMER_REAL, signal.ITIMER_VIRTUAL или signal.ITIMER_PROF), указанный в which, чтобы он сработал через seconds (принимается float, отличается от alarm()) и после этого через каждые interval секунд. Таймер интервалов, указанный в which, можно сбросить, установив seconds в ноль.

При срабатывании таймера интервалов в процесс отправляется сигнал. Отправляемый сигнал зависит от используемого таймера; signal.ITIMER_REAL отправит SIGALRM, signal.ITIMER_VIRTUAL отправит SIGVTALRM, а signal.ITIMER_PROF отправит SIGPROF.

Возвращаются старые значения в виде кортежа: (delay, interval).

Попытка передать недействительный таймер интервалов вызовет ItimerError. Доступность: Unix.

signal.getitimer(which)

Возвращает текущее значение заданного таймера интервалов, указанного в which. Доступность: Unix.

signal.set_wakeup_fd(fd)

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

Возвращается старый дескриптор файла пробуждения (или -1, если пробуждение по дескриптору файла не было включено). Если fd равно -1, пробуждение по дескриптору файла отключается. Если не -1, fd должен быть неблокирующим. Библиотека должна удалить все байты из fd перед повторным вызовом poll или select.

Используйте, например, struct.unpack('%uB' % len(data), data) для декодирования списка номеров сигналов.

При включённых потоках эту функцию можно вызывать только из главного потока; попытка вызова из других потоков приведёт к возбуждению исключения ValueError.

Изменено в версии 3.5: В Windows функция теперь также поддерживает сокет-дескрипторы.

signal.siginterrupt(signalnum, flag)

Изменить поведение перезапуска системного вызова: если flag равно False, системные вызовы будут перезапущены при прерывании сигналом signalnum, в противном случае системные вызовы будут прерваны. Ничего не возвращает. Доступность: Unix (см. страницу справки siginterrupt(3) для дополнительной информации).

Обратите внимание, что установка обработчика сигнала с помощью signal() сбросит поведение перезапуска, сделав его прерывимым, неявно вызвав siginterrupt() со значением flag true для данного сигнала.

signal.signal(signalnum, handler)

Устанавливает обработчик для сигнала signalnum на функцию handler. handler может быть вызываемым объектом Python, принимающим два аргумента (см. ниже), или одним из специальных значений signal.SIG_IGN или signal.SIG_DFL. Предыдущий обработчик сигнала будет возвращён (см. описание getsignal() выше). (См. страницу справки Unix signal(2).)

При включённых потоках эту функцию можно вызывать только из главного потока; попытка вызова из других потоков приведёт к возбуждению исключения ValueError.

Функция handler вызывается с двумя аргументами: номером сигнала и текущей кадровой частью стека (None или объектом кадра; для описания объектов кадра см. описание в иерархии типов или см. описания атрибутов в модуле inspect).

В Windows, signal() может быть вызван только со значениями SIGABRT, SIGFPE, SIGILL, SIGINT, SIGSEGV, SIGTERM, или SIGBREAK. В любом другом случае будет возбуждено исключение ValueError. Обратите внимание, что не все системы определяют один и тот же набор имён сигналов; исключение AttributeError будет возбуждено, если имя сигнала не определено в качестве константы уровня модуля SIG*.

signal.sigpending()

Отобразить набор сигналов, ожидающих обработки вызывающей нитью (т.е., сигналы, которые были подняты во время блокировки). Возвращает набор ожидающих сигналов.

Доступность: Unix (см. страницу руководства sigpending(2) для получения дополнительной информации).

См. также pause(), pthread_sigmask() и sigwait().

Введено в версии 3.3.

signal.sigwait(sigset)

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

Доступность: Unix (см. страницу руководства sigwait(3) для получения дополнительной информации).

См. также pause(), pthread_sigmask(), sigpending(), sigwaitinfo() и sigtimedwait().

Введено в версии 3.3.

signal.sigwaitinfo(sigset)

Приостановить выполнение вызывающей нити до получения одного из сигналов, указанных в наборе сигналов sigset. Функция принимает сигнал и удаляет его из списка ожидающих сигналов. Если один из сигналов в sigset уже ожидает обработки вызывающей нитью, функция вернётся немедленно с информацией об этом сигнале. Обработчик сигнала не вызывается для полученного сигнала. Функция вызывает исключение InterruptedError, если она прервана сигналом, не входящим в sigset.

Возвращаемое значение — объект, представляющий данные, содержащиеся в структуре siginfo_t, а именно: si_signo, si_code, si_errno, si_pid, si_uid, si_status, si_band.

Доступность: Unix (см. страницу руководства sigwaitinfo(2) для получения дополнительной информации).

См. также pause(), sigwait() и sigtimedwait().

Введено в версии 3.3.

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

signal.sigtimedwait(sigset, timeout)

Аналогично sigwaitinfo(), но принимает дополнительный аргумент timeout, указывающий таймаут. Если timeout задан как 0, выполняется проверка. Возвращает None, если таймаут истек.

Доступность: Unix (см. страницу руководства sigtimedwait(2) для получения дополнительной информации).

См. также pause(), sigwait() и sigwaitinfo().

Введено в версии 3.3.

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

3. Пример

Вот минимальная примерная программа. Она использует функцию alarm() для ограничения времени ожидания открытия файла; это полезно, если файл предназначен для последовательного устройства, которое может быть выключено, что обычно приводит к зависанию os.open() бесконечно. Решение заключается в установке сигнала тревоги на 5 секунд перед открытием файла; если операция занимает слишком много времени, сигнал тревоги будет отправлен, и обработчик вызовет исключение.

import signal, os

def handler(signum, frame):
    print('Signal handler called with signal', signum)
    raise OSError("Couldn't open device!")

# Set the signal handler and a 5-second alarm
signal.signal(signal.SIGALRM, handler)
signal.alarm(5)

# This open() may hang indefinitely
fd = os.open('/dev/ttyS0', os.O_RDWR)

signal.alarm(0)          # Disable the alarm

© 2001–2020 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.5/library/signal.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API