signal — Установка обработчиков асинхронных событий
Этот модуль предоставляет механизмы для использования обработчиков сигналов в Python.
18.8.1. Общие правила
Функция signal.signal() позволяет определять пользовательские обработчики, которые будут выполняться при получении сигнала. Небольшое количество обработчиков по умолчанию установлено: SIGPIPE игнорируется (чтобы ошибки записи в каналы и сокеты могли быть сообщены как обычные исключения Python) и SIGINT преобразуется в исключение KeyboardInterrupt.
Обработчик для конкретного сигнала, после установки, остается установленным до его явного сброса (Python эмулирует интерфейс в стиле BSD независимо от реализации базового уровня), за исключением обработчика для SIGCHLD, который следует базовой реализации.
18.8.1.1. Выполнение обработчиков сигналов Python
Обработчик сигнала Python не выполняется внутри обработчика сигнала низкого уровня (C). Вместо этого обработчик сигнала низкого уровня устанавливает флаг, который сообщает виртуальной машине виртуальной машине выполнить соответствующий обработчик сигнала Python в более поздний момент (например, в следующей инструкции байткода). Это имеет последствия:
- Это мало имеет смысла для обработки синхронных ошибок, таких как
SIGFPEилиSIGSEGV, которые вызваны недопустимой операцией в коде C. Python вернется из обработчика сигнала в код C, который, вероятно, снова вызовет тот же сигнал, что приведет к тому, что Python, по-видимому, зависнет. Начиная с Python 3.3, вы можете использовать модульfaulthandlerдля отчета о синхронных ошибках. - Многозадачная вычисления, реализованная исключительно на C (например, сопоставление регулярных выражений с большой частью текста), может выполняться без прерывания неопределенно долго, независимо от полученных сигналов. Обработчики сигналов Python будут вызваны, когда вычисление завершится.
18.8.1.2. Сигналы и потоки
Обработчики сигналов Python всегда выполняются в главном потоке Python, даже если сигнал был получен в другом потоке. Это означает, что сигналы не могут использоваться в качестве средства межпотоковой коммуникации. Вместо этого можно использовать средства синхронизации из модуля threading.
Кроме того, только главный поток может установить новый обработчик сигнала.
18.8.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 -
Возможная величина параметра как для
pthread_sigmask()указывающая на то, что сигналы должны быть заблокированы.Новое в версии 3.3.
-
signal.SIG_UNBLOCK -
Возможная величина параметра как для
pthread_sigmask()указывающая на то, что сигналы должны быть разблокированы.Новое в версии 3.3.
-
signal.SIG_SETMASK -
Возможная величина параметра как для
pthread_sigmask()указывающая на то, что маска сигнала должна быть заменена.Новое в версии 3.3.
Модуль signal определяет одно исключение:
-
exception signal.ItimerError -
Выбрасывается для сигнализации об ошибке при выполнении базовой реализации
setitimer()илиgetitimer(). Ожидайте эту ошибку, если вsetitimer()передан недопустимый таймер интервала или отрицательное время. Эта ошибка является подтипомOSError.
Модуль signal определяет следующие функции:
-
signal.alarm(time) -
Если time не равно нулю, эта функция запрашивает отправку сигнала
SIGALRMпроцессу через time секунд. Любой ранее запланированный сигнал тревоги отменяется (одновременно может быть запланирован только один сигнал тревоги). Возвращаемое значение — это количество секунд до момента, когда должен был быть доставлен любой ранее установленный сигнал тревоги. Если time равно нулю, сигнал тревоги не планируется, а любой запланированный сигнал тревоги отменяется. Если возвращаемое значение равно нулю, в настоящее время сигнал тревоги не запланирован. (См. страницу руководства Unix alarm(2).) Доступность: Unix.
-
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 (принимается число с плавающей точкой, отличается от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()со значением true для flag заданного сигнала.
-
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. Обратите внимание, что не все системы определяют один и тот же набор имён сигналов; если имя сигнала не определено как константа уровня модуляSIG*, будет возбуждено исключениеAttributeError.
-
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 для обоснования).
18.8.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.6/library/signal.html