signal.md
1> **Источник:** https://python-all.ru/3.8/library/signal.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# [`signal`](https://python-all.ru/3.8/library/signal.html#module-signal) – Установка обработчиков асинхронных событий89---1011Этот модуль предоставляет механизмы для использования обработчиков сигналов в Python.1213## Общие правила1415Функция [`signal.signal()`](https://python-all.ru/3.8/library/signal.html#signal.signal) позволяет определять пользовательские обработчики, выполняемые при получении сигнала. Небольшое количество обработчиков по умолчанию установлено: сигнал [`SIGPIPE`](https://python-all.ru/3.8/library/signal.html#signal.SIGPIPE) игнорируется (поэтому ошибки записи в каналы и сокеты могут сообщаться как обычные исключения Python), а сигнал [`SIGINT`](https://python-all.ru/3.8/library/signal.html#signal.SIGINT) преобразуется в исключение [`KeyboardInterrupt`](https://python-all.ru/3.8/library/exceptions.html#KeyboardInterrupt), если родительский процесс не изменил его.1617Обработчик конкретного сигнала после установки остается активным до явной переустановки (Python эмулирует интерфейс в стиле BSD независимо от реализации), за исключением обработчика для [`SIGCHLD`](https://python-all.ru/3.8/library/signal.html#signal.SIGCHLD), который следует базовой реализации.1819### Выполнение обработчиков сигналов Python2021Обработчик сигналов Python не выполняется внутри низкоуровневого (C) обработчика сигналов. Вместо этого низкоуровневый обработчик устанавливает флаг, который сообщает [виртуальной машине](https://python-all.ru/3.8/glossary.html#term-virtual-machine) выполнить соответствующий обработчик Python позже (например, на следующей инструкции [байткода](https://python-all.ru/3.8/glossary.html#term-bytecode)). Это имеет последствия:2223- Ловить синхронные ошибки вроде [`SIGFPE`](https://python-all.ru/3.8/library/signal.html#signal.SIGFPE) или [`SIGSEGV`](https://python-all.ru/3.8/library/signal.html#signal.SIGSEGV), вызванные недопустимой операцией в коде C, не имеет смысла. Python вернется от обработчика сигнала к коду C, который, скорее всего, снова возбудит тот же сигнал, что приведет к зависанию Python. Начиная с Python 3.3 можно использовать модуль [`faulthandler`](https://python-all.ru/3.8/library/faulthandler.html#module-faulthandler) для сообщения о синхронных ошибках.24- Длительное вычисление, реализованное чисто на C (например, сравнение с регулярным выражением по большому объему текста), может выполняться без прерывания сколь угодно долго, независимо от полученных сигналов. Обработчики сигналов Python будут вызваны по завершении вычисления.2526### Сигналы и потоки2728Обработчики сигналов Python всегда выполняются в главном потоке Python, даже если сигнал был получен в другом потоке. Это означает, что сигналы нельзя использовать для межпоточной коммуникации. Вместо этого можно использовать примитивы синхронизации из модуля [`threading`](https://python-all.ru/3.8/library/threading.html#module-threading).2930Кроме того, только главный поток может устанавливать новый обработчик сигнала.3132## Содержимое модуля3334Изменено в версии 3.5: signal (SIG\*), handler ([`SIG_DFL`](https://python-all.ru/3.8/library/signal.html#signal.SIG_DFL), [`SIG_IGN`](https://python-all.ru/3.8/library/signal.html#signal.SIG_IGN)) и sigmask ([`SIG_BLOCK`](https://python-all.ru/3.8/library/signal.html#signal.SIG_BLOCK), [`SIG_UNBLOCK`](https://python-all.ru/3.8/library/signal.html#signal.SIG_UNBLOCK), [`SIG_SETMASK`](https://python-all.ru/3.8/library/signal.html#signal.SIG_SETMASK)) и перечисленные ниже константы были преобразованы в [`enums`](https://python-all.ru/3.8/library/enum.html#enum.IntEnum). Функции [`getsignal()`](https://python-all.ru/3.8/library/signal.html#signal.getsignal), [`pthread_sigmask()`](https://python-all.ru/3.8/library/signal.html#signal.pthread_sigmask), [`sigpending()`](https://python-all.ru/3.8/library/signal.html#signal.sigpending) и [`sigwait()`](https://python-all.ru/3.8/library/signal.html#signal.sigwait) возвращают человекочитаемые [`enums`](https://python-all.ru/3.8/library/enum.html#enum.IntEnum).3536Переменные, определенные в модуле [`signal`](https://python-all.ru/3.8/library/signal.html#module-signal):3738#### `signal.SIG_DFL`3940Это один из двух стандартных вариантов обработки сигналов; он просто выполняет функцию по умолчанию для сигнала. Например, на большинстве систем действие по умолчанию для `SIGQUIT` – сбросить дамп ядра и завершиться, тогда как действие по умолчанию для [`SIGCHLD`](https://python-all.ru/3.8/library/signal.html#signal.SIGCHLD) – просто игнорировать его.4142#### `signal.SIG_IGN`4344Это еще один стандартный обработчик сигнала, который просто игнорирует данный сигнал.4546#### `signal.SIGABRT`4748Сигнал прерывания от *[abort(3)](https://python-all.ru/3.8/library/signal.html)*.4950#### `signal.SIGALRM`5152Сигнал таймера от *[alarm(2)](https://python-all.ru/3.8/library/signal.html)*.5354[Доступность](https://python-all.ru/3.8/library/intro.html#availability): Unix.5556#### `signal.SIGBREAK`5758Прерывание с клавиатуры (CTRL + BREAK).5960[Доступность](https://python-all.ru/3.8/library/intro.html#availability): Windows.6162#### `signal.SIGBUS`6364Ошибка шины (неверный доступ к памяти).6566[Доступность](https://python-all.ru/3.8/library/intro.html#availability): Unix.6768#### `signal.SIGCHLD`6970Дочерний процесс остановлен или завершён.7172[Доступность](https://python-all.ru/3.8/library/intro.html#availability): Unix.7374#### `signal.SIGCLD`7576Псевдоним для [`SIGCHLD`](https://python-all.ru/3.8/library/signal.html#signal.SIGCHLD).7778#### `signal.SIGCONT`7980Продолжить процесс, если он в данный момент остановлен8182[Доступность](https://python-all.ru/3.8/library/intro.html#availability): Unix.8384#### `signal.SIGFPE`8586Исключение с плавающей запятой. Например, деление на ноль.8788> **См. также**89>90> [`ZeroDivisionError`](https://python-all.ru/3.8/library/exceptions.html#ZeroDivisionError) возникает, когда второй аргумент операции деления или взятия остатка равен нулю.9192#### `signal.SIGHUP`9394Обнаружен обрыв связи на управляющем терминале или завершение управляющего процесса.9596[Доступность](https://python-all.ru/3.8/library/intro.html#availability): Unix.9798#### `signal.SIGILL`99100Недопустимая инструкция.101102#### `signal.SIGINT`103104Прерывание с клавиатуры (CTRL + C).105106Действие по умолчанию – возбудить [`KeyboardInterrupt`](https://python-all.ru/3.8/library/exceptions.html#KeyboardInterrupt).107108#### `signal.SIGKILL`109110Сигнал уничтожения.111112Его нельзя перехватить, заблокировать или проигнорировать.113114[Доступность](https://python-all.ru/3.8/library/intro.html#availability): Unix.115116#### `signal.SIGPIPE`117118Разрыв канала: запись в канал без читателей.119120Действие по умолчанию – игнорировать сигнал.121122[Доступность](https://python-all.ru/3.8/library/intro.html#availability): Unix.123124#### `signal.SIGSEGV`125126Ошибка сегментации: неверная ссылка на память.127128#### `signal.SIGTERM`129130Сигнал завершения.131132#### `signal.SIGUSR1`133134Пользовательский сигнал 1.135136[Доступность](https://python-all.ru/3.8/library/intro.html#availability): Unix.137138#### `signal.SIGUSR2`139140Пользовательский сигнал 2.141142[Доступность](https://python-all.ru/3.8/library/intro.html#availability): Unix.143144#### `signal.SIGWINCH`145146Сигнал изменения размера окна.147148[Доступность](https://python-all.ru/3.8/library/intro.html#availability): Unix.149150#### `SIG*`151152Все номера сигналов определены символически. Например, сигнал сброса определен как [`signal.SIGHUP`](https://python-all.ru/3.8/library/signal.html#signal.SIGHUP); имена переменных идентичны именам, используемым в программах на C, как в `<signal.h>`. В man-странице Unix для ‘`signal()`’ перечислены существующие сигналы (в некоторых системах это *[signal(2)](https://python-all.ru/3.8/library/signal.html)*, в других список находится в *[signal(7)](https://python-all.ru/3.8/library/signal.html)*). Обратите внимание, что не все системы определяют одинаковый набор имен сигналов; только те имена, которые определены системой, определены в этом модуле.153154#### `signal.CTRL_C_EVENT`155156Сигнал, соответствующий нажатию клавиши `Ctrl+C`. Этот сигнал можно использовать только с [`os.kill()`](https://python-all.ru/3.8/library/os.html#os.kill).157158[Доступность](https://python-all.ru/3.8/library/intro.html#availability): Windows.159160Новое в версии 3.2.161162#### `signal.CTRL_BREAK_EVENT`163164Сигнал, соответствующий нажатию клавиши `Ctrl+Break`. Этот сигнал можно использовать только с [`os.kill()`](https://python-all.ru/3.8/library/os.html#os.kill).165166[Доступность](https://python-all.ru/3.8/library/intro.html#availability): Windows.167168Новое в версии 3.2.169170#### `signal.NSIG`171172На единицу больше номера самого высокого сигнала.173174#### `signal.ITIMER_REAL`175176Уменьшает интервальный таймер в реальном времени и отправляет [`SIGALRM`](https://python-all.ru/3.8/library/signal.html#signal.SIGALRM) по истечении.177178#### `signal.ITIMER_VIRTUAL`179180Уменьшает интервальный таймер только во время выполнения процесса и отправляет SIGVTALRM по истечении.181182#### `signal.ITIMER_PROF`183184Уменьшает интервальный таймер как при выполнении процесса, так и при выполнении системой от имени процесса. В паре с ITIMER\_VIRTUAL этот таймер обычно используется для профилирования времени, затраченного приложением в пользовательском и ядерном пространстве. SIGPROF доставляется по истечении времени.185186#### `signal.SIG_BLOCK`187188Возможное значение параметра *how* функции [`pthread_sigmask()`](https://python-all.ru/3.8/library/signal.html#signal.pthread_sigmask), указывающее, что сигналы должны быть заблокированы.189190Новое в версии 3.3.191192#### `signal.SIG_UNBLOCK`193194Возможное значение параметра *how* функции [`pthread_sigmask()`](https://python-all.ru/3.8/library/signal.html#signal.pthread_sigmask), указывающее, что сигналы должны быть разблокированы.195196Новое в версии 3.3.197198#### `signal.SIG_SETMASK`199200Возможное значение параметра *how* функции [`pthread_sigmask()`](https://python-all.ru/3.8/library/signal.html#signal.pthread_sigmask), указывающее, что маска сигналов должна быть заменена.201202Новое в версии 3.3.203204Модуль [`signal`](https://python-all.ru/3.8/library/signal.html#module-signal) определяет одно исключение:205206#### `exception signal.ItimerError`207208Возбуждается для указания на ошибку в реализации [`setitimer()`](https://python-all.ru/3.8/library/signal.html#signal.setitimer) или [`getitimer()`](https://python-all.ru/3.8/library/signal.html#signal.getitimer). Этого исключения следует ожидать, если некорректный интервальный таймер или отрицательное время передаются в [`setitimer()`](https://python-all.ru/3.8/library/signal.html#signal.setitimer). Это исключение является подтипом [`OSError`](https://python-all.ru/3.8/library/exceptions.html#OSError).209210Новое в версии 3.3: Раньше эта ошибка была подтипом [`IOError`](https://python-all.ru/3.8/library/exceptions.html#IOError), который теперь является синонимом [`OSError`](https://python-all.ru/3.8/library/exceptions.html#OSError).211212Модуль [`signal`](https://python-all.ru/3.8/library/signal.html#module-signal) определяет следующие функции:213214#### `signal.alarm(time)`215216Если *time* не равен нулю, эта функция запрашивает отправку сигнала [`SIGALRM`](https://python-all.ru/3.8/library/signal.html#signal.SIGALRM) процессу через *time* секунд. Любой ранее запланированный сигнал отменяется (в любой момент может быть запланирован только один сигнал). Возвращаемое значение – количество секунд до отправки предыдущего запланированного сигнала. Если *time* равно нулю, никакой сигнал не планируется, а любой запланированный отменяется. Если возвращаемое значение равно нулю, сигнал в настоящее время не запланирован.217218[Доступность](https://python-all.ru/3.8/library/intro.html#availability): Unix. См. справочную страницу *[alarm(2)](https://python-all.ru/3.8/library/signal.html)* для получения дополнительной информации.219220#### `signal.getsignal(signalnum)`221222Возвращает текущий обработчик сигнала *signalnum*. Возвращаемое значение может быть вызываемым объектом Python или одним из специальных значений [`signal.SIG_IGN`](https://python-all.ru/3.8/library/signal.html#signal.SIG_IGN), [`signal.SIG_DFL`](https://python-all.ru/3.8/library/signal.html#signal.SIG_DFL) или [`None`](https://python-all.ru/3.8/library/constants.html#None). Здесь [`signal.SIG_IGN`](https://python-all.ru/3.8/library/signal.html#signal.SIG_IGN) означает, что сигнал ранее игнорировался, [`signal.SIG_DFL`](https://python-all.ru/3.8/library/signal.html#signal.SIG_DFL) означает, что ранее использовался способ обработки сигнала по умолчанию, а `None` означает, что предыдущий обработчик сигнала не был установлен из Python.223224#### `signal.strsignal(signalnum)`225226Возвращает системное описание сигнала *signalnum*, например «Interrupt», «Segmentation fault» и т. д. Возвращает [`None`](https://python-all.ru/3.8/library/constants.html#None), если сигнал не распознан.227228Новое в версии 3.8.229230#### `signal.valid_signals()`231232Возвращает набор допустимых номеров сигналов на этой платформе. Он может быть меньше `range(1, NSIG)`, если некоторые сигналы зарезервированы системой для внутреннего использования.233234Новое в версии 3.8.235236#### `signal.pause()`237238Приостанавливает выполнение процесса до получения сигнала; затем будет вызван соответствующий обработчик. Ничего не возвращает.239240[Доступность](https://python-all.ru/3.8/library/intro.html#availability): Unix. См. справочную страницу *[signal(2)](https://python-all.ru/3.8/library/signal.html)* для получения дополнительной информации.241242См. также [`sigwait()`](https://python-all.ru/3.8/library/signal.html#signal.sigwait), [`sigwaitinfo()`](https://python-all.ru/3.8/library/signal.html#signal.sigwaitinfo), [`sigtimedwait()`](https://python-all.ru/3.8/library/signal.html#signal.sigtimedwait) и [`sigpending()`](https://python-all.ru/3.8/library/signal.html#signal.sigpending).243244#### `signal.raise_signal(signum)`245246Отправляет сигнал вызывающему процессу. Ничего не возвращает.247248Новое в версии 3.8.249250#### `signal.pthread_kill(thread_id, signalnum)`251252Посылает сигнал *signalnum* потоку *thread\_id*, другому потоку в том же процессе, что и вызывающий. Целевой поток может выполнять любой код (Python или нет). Однако, если целевой поток выполняет интерпретатор Python, обработчики сигналов Python будут [выполнены главным потоком](https://python-all.ru/3.8/library/signal.html#signals-and-threads). Следовательно, единственный смысл отправки сигнала конкретному потоку Python – это принудительное завершение работающего системного вызова с ошибкой [`InterruptedError`](https://python-all.ru/3.8/library/exceptions.html#InterruptedError).253254Используйте [`threading.get_ident()`](https://python-all.ru/3.8/library/threading.html#threading.get_ident) или атрибут [`ident`](https://python-all.ru/3.8/library/threading.html#threading.Thread.ident) объектов [`threading.Thread`](https://python-all.ru/3.8/library/threading.html#threading.Thread), чтобы получить подходящее значение для *thread\_id*.255256Если *signalnum* равен 0, сигнал не отправляется, но проверка ошибок по-прежнему выполняется; это можно использовать для проверки, работает ли целевой поток.257258Возбуждает [событие аудита](https://python-all.ru/3.8/library/sys.html#auditing) `signal.pthread_kill` с аргументами `thread_id`, `signalnum`.259260[Доступность](https://python-all.ru/3.8/library/intro.html#availability): Unix. См. справочную страницу *[pthread\_kill(3)](https://python-all.ru/3.8/library/signal.html)* для получения дополнительной информации.261262См. также [`os.kill()`](https://python-all.ru/3.8/library/os.html#os.kill).263264Новое в версии 3.3.265266#### `signal.pthread_sigmask(how, mask)`267268Получает и/или изменяет маску сигналов вызывающего потока. Маска сигналов – это набор сигналов, доставка которых в настоящий момент заблокирована для вызывающей стороны. Возвращает старую маску сигналов в виде набора сигналов.269270Поведение вызова зависит от значения *how* следующим образом.271272- [`SIG_BLOCK`](https://python-all.ru/3.8/library/signal.html#signal.SIG_BLOCK): Набор заблокированных сигналов – это объединение текущего набора и аргумента *mask*.273- [`SIG_UNBLOCK`](https://python-all.ru/3.8/library/signal.html#signal.SIG_UNBLOCK): Сигналы из *mask* удаляются из текущего набора заблокированных сигналов. Допускается попытка разблокировать сигнал, который не был заблокирован.274- [`SIG_SETMASK`](https://python-all.ru/3.8/library/signal.html#signal.SIG_SETMASK): Набор заблокированных сигналов устанавливается равным аргументу *mask*.275276*mask* – это набор номеров сигналов (например, {[`signal.SIGINT`](https://python-all.ru/3.8/library/signal.html#signal.SIGINT), [`signal.SIGTERM`](https://python-all.ru/3.8/library/signal.html#signal.SIGTERM)}). Используйте [`valid_signals()`](https://python-all.ru/3.8/library/signal.html#signal.valid_signals) для полной маски, включающей все сигналы.277278Например, `signal.pthread_sigmask(signal.SIG_BLOCK, [])` считывает маску сигналов вызывающего потока.279280[`SIGKILL`](https://python-all.ru/3.8/library/signal.html#signal.SIGKILL) и `SIGSTOP` не могут быть заблокированы.281282[Доступность](https://python-all.ru/3.8/library/intro.html#availability): Unix. См. man-страницы *[sigprocmask(3)](https://python-all.ru/3.8/library/signal.html)* и *[pthread\_sigmask(3)](https://python-all.ru/3.8/library/signal.html)* для получения дополнительной информации.283284См. также [`pause()`](https://python-all.ru/3.8/library/signal.html#signal.pause), [`sigpending()`](https://python-all.ru/3.8/library/signal.html#signal.sigpending) и [`sigwait()`](https://python-all.ru/3.8/library/signal.html#signal.sigwait).285286Новое в версии 3.3.287288#### `signal.setitimer(which, seconds, interval=0.0)`289290Устанавливает заданный интервальный таймер (один из [`signal.ITIMER_REAL`](https://python-all.ru/3.8/library/signal.html#signal.ITIMER_REAL), [`signal.ITIMER_VIRTUAL`](https://python-all.ru/3.8/library/signal.html#signal.ITIMER_VIRTUAL) или [`signal.ITIMER_PROF`](https://python-all.ru/3.8/library/signal.html#signal.ITIMER_PROF)), указанный параметром *which*, чтобы он срабатывал через *seconds* (допускается число с плавающей точкой, в отличие от [`alarm()`](https://python-all.ru/3.8/library/signal.html#signal.alarm)) и затем каждые *interval* секунд (если *interval* не равен нулю). Интервальный таймер, заданный через *which*, можно сбросить, установив *seconds* равным нулю.291292Когда срабатывает интервальный таймер, процессу отправляется сигнал. Отправляемый сигнал зависит от используемого таймера: [`signal.ITIMER_REAL`](https://python-all.ru/3.8/library/signal.html#signal.ITIMER_REAL) доставляет [`SIGALRM`](https://python-all.ru/3.8/library/signal.html#signal.SIGALRM), [`signal.ITIMER_VIRTUAL`](https://python-all.ru/3.8/library/signal.html#signal.ITIMER_VIRTUAL) отправляет `SIGVTALRM`, а [`signal.ITIMER_PROF`](https://python-all.ru/3.8/library/signal.html#signal.ITIMER_PROF) доставляет `SIGPROF`.293294Старые значения возвращаются в виде кортежа: (delay, interval).295296Попытка передать недопустимый интервальный таймер приведет к [`ItimerError`](https://python-all.ru/3.8/library/signal.html#signal.ItimerError).297298[Доступность](https://python-all.ru/3.8/library/intro.html#availability): Unix.299300#### `signal.getitimer(which)`301302Возвращает текущее значение заданного интервального таймера, указанного параметром *which*.303304[Доступность](https://python-all.ru/3.8/library/intro.html#availability): Unix.305306#### `signal.set_wakeup_fd(fd, *, warn_on_full_buffer=True)`307308Устанавливает дескриптор файла пробуждения в *fd*. Когда сигнал получен, номер сигнала записывается в fd как один байт. Это может быть использовано библиотекой для пробуждения вызова poll или select, позволяя полностью обработать сигнал.309310Возвращается старый fd пробуждения (или -1, если пробуждение через файловый дескриптор не было включено). Если *fd* равен -1, пробуждение через файловый дескриптор отключается. Если не -1, то *fd* должен быть неблокирующим. Задача библиотеки – удалить все байты из *fd* перед повторным вызовом poll или select.311312Когда потоки включены, эту функцию можно вызывать только из главного потока; попытка вызова из других потоков приведет к возникновению исключения [`ValueError`](https://python-all.ru/3.8/library/exceptions.html#ValueError).313314Существует два распространенных способа использования этой функции. В обоих подходах используется fd для пробуждения при поступлении сигнала, но затем они различаются тем, как определяют, *which* сигнал или сигналы поступили.315316В первом подходе данные читаются из буфера fd, и значения байтов дают номера сигналов. Это просто, но в редких случаях может возникнуть проблема: обычно fd имеет ограниченный объём буфера, и если слишком много сигналов приходит слишком быстро, буфер может переполниться, и некоторые сигналы могут быть потеряны. Если используется этот подход, следует установить `warn_on_full_buffer=True`, что, по крайней мере, приведет к выводу предупреждения в stderr при потере сигналов.317318Во втором подходе fd пробуждения используется *only* для пробуждения, а фактические значения байтов игнорируются. В этом случае важно лишь то, пуст буфер fd или нет; полный буфер не свидетельствует о проблеме. Если используется этот подход, следует установить `warn_on_full_buffer=False`, чтобы пользователи не сбивались с толку ложными предупреждениями.319320Изменено в версии 3.5: В Windows функция теперь также поддерживает дескрипторы сокетов.321322Изменено в версии 3.7: Добавлен параметр `warn_on_full_buffer`.323324#### `signal.siginterrupt(signalnum, flag)`325326Изменяет поведение перезапуска системных вызовов: если *flag* равен [`False`](https://python-all.ru/3.8/library/constants.html#False), системные вызовы будут перезапускаться при прерывании сигналом *signalnum*, в противном случае системные вызовы будут прерваны. Ничего не возвращает.327328[Доступность](https://python-all.ru/3.8/library/intro.html#availability): Unix. См. справочную страницу *[siginterrupt(3)](https://python-all.ru/3.8/library/signal.html)* для получения дополнительной информации.329330Обратите внимание, что установка обработчика сигнала с помощью [`signal()`](https://python-all.ru/3.8/library/signal.html#module-signal) сбрасывает поведение перезапуска на прерываемое, неявно вызывая `siginterrupt()` со значением *flag*, равным true, для данного сигнала.331332#### `signal.signal(signalnum, handler)`333334Устанавливает обработчик для сигнала *signalnum* в функцию *handler*. *handler* может быть вызываемым объектом Python, принимающим два аргумента (см. ниже), или одним из специальных значений [`signal.SIG_IGN`](https://python-all.ru/3.8/library/signal.html#signal.SIG_IGN) или [`signal.SIG_DFL`](https://python-all.ru/3.8/library/signal.html#signal.SIG_DFL). Возвращается предыдущий обработчик сигнала (см. описание [`getsignal()`](https://python-all.ru/3.8/library/signal.html#signal.getsignal) выше). (За дополнительной информацией обращайтесь к man-странице Unix *[signal(2)](https://python-all.ru/3.8/library/signal.html)*.)335336Когда потоки включены, эту функцию можно вызывать только из главного потока; попытка вызова из других потоков приведет к возникновению исключения [`ValueError`](https://python-all.ru/3.8/library/exceptions.html#ValueError).337338*handler* вызывается с двумя аргументами: номером сигнала и текущим стековым кадром (`None` или объектом кадра; описание объектов кадра см. в [описании в иерархии типов](https://python-all.ru/3.8/reference/datamodel.html#frame-objects) или в описаниях атрибутов модуля [`inspect`](https://python-all.ru/3.8/library/inspect.html#module-inspect)).339340В Windows [`signal()`](https://python-all.ru/3.8/library/signal.html#module-signal) можно вызывать только с [`SIGABRT`](https://python-all.ru/3.8/library/signal.html#signal.SIGABRT), [`SIGFPE`](https://python-all.ru/3.8/library/signal.html#signal.SIGFPE), [`SIGILL`](https://python-all.ru/3.8/library/signal.html#signal.SIGILL), [`SIGINT`](https://python-all.ru/3.8/library/signal.html#signal.SIGINT), [`SIGSEGV`](https://python-all.ru/3.8/library/signal.html#signal.SIGSEGV), [`SIGTERM`](https://python-all.ru/3.8/library/signal.html#signal.SIGTERM) или [`SIGBREAK`](https://python-all.ru/3.8/library/signal.html#signal.SIGBREAK). В любом другом случае будет возбуждено [`ValueError`](https://python-all.ru/3.8/library/exceptions.html#ValueError). Обратите внимание, что не все системы определяют одинаковый набор имён сигналов; [`AttributeError`](https://python-all.ru/3.8/library/exceptions.html#AttributeError) будет возбуждено, если имя сигнала не определено как константа уровня модуля `SIG*`.341342#### `signal.sigpending()`343344Проверяет набор сигналов, ожидающих доставки вызывающему потоку (т.е. сигналы, которые были подняты, пока были заблокированы). Возвращает набор ожидающих сигналов.345346[Доступность](https://python-all.ru/3.8/library/intro.html#availability): Unix. См. справочную страницу *[sigpending(2)](https://python-all.ru/3.8/library/signal.html)* для получения дополнительной информации.347348См. также [`pause()`](https://python-all.ru/3.8/library/signal.html#signal.pause), [`pthread_sigmask()`](https://python-all.ru/3.8/library/signal.html#signal.pthread_sigmask) и [`sigwait()`](https://python-all.ru/3.8/library/signal.html#signal.sigwait).349350Новое в версии 3.3.351352#### `signal.sigwait(sigset)`353354Приостанавливает выполнение вызывающего потока до доставки одного из сигналов, указанных в наборе сигналов *sigset*. Функция принимает сигнал (удаляет его из списка ожидающих сигналов) и возвращает номер сигнала.355356[Доступность](https://python-all.ru/3.8/library/intro.html#availability): Unix. См. справочную страницу *[sigwait(3)](https://python-all.ru/3.8/library/signal.html)* для получения дополнительной информации.357358См. также [`pause()`](https://python-all.ru/3.8/library/signal.html#signal.pause), [`pthread_sigmask()`](https://python-all.ru/3.8/library/signal.html#signal.pthread_sigmask), [`sigpending()`](https://python-all.ru/3.8/library/signal.html#signal.sigpending), [`sigwaitinfo()`](https://python-all.ru/3.8/library/signal.html#signal.sigwaitinfo) и [`sigtimedwait()`](https://python-all.ru/3.8/library/signal.html#signal.sigtimedwait).359360Новое в версии 3.3.361362#### `signal.sigwaitinfo(sigset)`363364Приостанавливает выполнение вызывающего потока до доставки одного из сигналов, указанных в наборе сигналов *sigset*. Функция принимает сигнал и удаляет его из списка ожидающих сигналов. Если один из сигналов в *sigset* уже ожидает вызывающий поток, функция немедленно вернётся с информацией об этом сигнале. Обработчик сигнала не вызывается для доставленного сигнала. Функция возбуждает [`InterruptedError`](https://python-all.ru/3.8/library/exceptions.html#InterruptedError), если она была прервана сигналом, которого нет в *sigset*.365366Возвращаемое значение – объект, представляющий данные, содержащиеся в структуре `siginfo_t`, а именно: `si_signo`, `si_code`, `si_errno`, `si_pid`, `si_uid`, `si_status`, `si_band`.367368[Доступность](https://python-all.ru/3.8/library/intro.html#availability): Unix. См. справочную страницу *[sigwaitinfo(2)](https://python-all.ru/3.8/library/signal.html)* для получения дополнительной информации.369370См. также [`pause()`](https://python-all.ru/3.8/library/signal.html#signal.pause), [`sigwait()`](https://python-all.ru/3.8/library/signal.html#signal.sigwait) и [`sigtimedwait()`](https://python-all.ru/3.8/library/signal.html#signal.sigtimedwait).371372Новое в версии 3.3.373374Изменено в версии 3.5: Теперь функция повторяется, если прервана сигналом, не входящим в *sigset*, и обработчик сигнала не возбуждает исключение (см. [**PEP 475**](https://python-all.ru/3.8/library/signal.html) для обоснования).375376#### `signal.sigtimedwait(sigset, timeout)`377378Как [`sigwaitinfo()`](https://python-all.ru/3.8/library/signal.html#signal.sigwaitinfo), но принимает дополнительный аргумент *timeout*, указывающий тайм-аут. Если *timeout* указан как `0`, выполняется опрос. Возвращает [`None`](https://python-all.ru/3.8/library/constants.html#None) при наступлении тайм-аута.379380[Доступность](https://python-all.ru/3.8/library/intro.html#availability): Unix. См. справочную страницу *[sigtimedwait(2)](https://python-all.ru/3.8/library/signal.html)* для получения дополнительной информации.381382См. также [`pause()`](https://python-all.ru/3.8/library/signal.html#signal.pause), [`sigwait()`](https://python-all.ru/3.8/library/signal.html#signal.sigwait) и [`sigwaitinfo()`](https://python-all.ru/3.8/library/signal.html#signal.sigwaitinfo).383384Новое в версии 3.3.385386Изменено в версии 3.5: Теперь функция повторяется с пересчитанным *timeout*, если прервана сигналом, не входящим в *sigset*, и обработчик сигнала не возбуждает исключение (см. [**PEP 475**](https://python-all.ru/3.8/library/signal.html) для обоснования).387388## Пример389390Вот минимальный пример программы. Она использует функцию [`alarm()`](https://python-all.ru/3.8/library/signal.html#signal.alarm) для ограничения времени, затрачиваемого на ожидание открытия файла; это полезно, если файл находится на последовательном устройстве, которое может быть выключено, что обычно приводит к бесконечному зависанию [`os.open()`](https://python-all.ru/3.8/library/os.html#os.open). Решение – установить 5-секундный будильник перед открытием файла; если операция занимает слишком много времени, будет отправлен сигнал будильника, и обработчик возбудит исключение.391392```python393import signal, os394395def handler(signum, frame):396 print('Signal handler called with signal', signum)397 raise OSError("Couldn't open device!")398399# Установить обработчик сигнала и 5-секундный будильник400signal.signal(signal.SIGALRM, handler)401signal.alarm(5)402403# Этот вызов open() может зависнуть навсегда404fd = os.open('/dev/ttyS0', os.O_RDWR)405406signal.alarm(0) # Отключить будильник407```408409## Примечание о SIGPIPE410411Перенаправление вывода программы через конвейер в такие утилиты, как *[head(1)](https://python-all.ru/3.8/library/signal.html)*, приводит к отправке сигнала [`SIGPIPE`](https://python-all.ru/3.8/library/signal.html#signal.SIGPIPE) процессу, когда получатель его стандартного вывода закрывается рано. Это вызывает исключение, подобное `BrokenPipeError: [Errno 32] Broken pipe`. Для обработки этого случая точку входа следует обернуть для перехвата этого исключения следующим образом:412413```python414import os415import sys416417def main():418 try:419 # имитировать большой объем вывода (ваш код заменяет этот цикл)420 for x in range(10000):421 print("y")422 # сбросить вывод здесь, чтобы принудительно вызвать SIGPIPE423 # пока внутри этого блока try.424 sys.stdout.flush()425 except BrokenPipeError:426 # Python сбрасывает стандартные потоки при выходе; перенаправьте оставшийся вывод в /dev/null, чтобы избежать ещё одного BrokenPipeError при завершении работы.427 # в devnull, чтобы избежать еще одного BrokenPipeError при завершении428 devnull = os.open(os.devnull, os.O_WRONLY)429 os.dup2(devnull, sys.stdout.fileno())430 sys.exit(1) # Python завершается с кодом ошибки 1 при EPIPE431432if __name__ == '__main__':433 main()434```435436Не устанавливайте обработчик [`SIGPIPE`](https://python-all.ru/3.8/library/signal.html#signal.SIGPIPE) в [`SIG_DFL`](https://python-all.ru/3.8/library/signal.html#signal.SIG_DFL), чтобы избежать [`BrokenPipeError`](https://python-all.ru/3.8/library/exceptions.html#BrokenPipeError). Это приведет к неожиданному завершению программы всякий раз, когда соединение через сокет будет прервано во время записи в него.437