Сигнал (IPC)

редактировать
Форма межпроцессного взаимодействия в компьютерных системах

Сигналы - это ограниченная форма inter -процессная связь (IPC), обычно используется в Unix, Unix-like и других POSIX -совместимых операционных системах. Сигнал - это асинхронное уведомление, отправленное процессу или конкретному потоку в том же процессе, чтобы уведомить его о произошедшем событии. Сигналы возникли в 1970-х годах Bell Labs Unix и недавно были определены в стандарте POSIX.

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

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

Сигналы аналогичны прерываниям, разница в том, что прерывания опосредуются процессором и обрабатываются ядром, в то время как сигналы опосредуются ядром (возможно, через систему вызовы) и обрабатываются процессами. Ядро может передать прерывание в качестве сигнала вызвавшему его процессу (типичные примеры: SIGSEGV, SIGBUS, SIGILL и SIGFPE).

Содержание
  • 1 История
  • 2 Отправка сигналов
  • 3 Обработка сигналов
    • 3.1 Риски
  • 4 Связь с аппаратными исключениями
  • 5 Сигналы POSIX
    • 5.1 Действие по умолчанию
  • 6 Разные сигналы
  • 7 См. Также
  • 8 Ссылки
  • 9 Внешние ссылки
История

Версия 1 Unix имела отдельные системные вызовы для перехвата прерываний, завершения и обработки ловушки. Версия 4 объединила все ловушки в один вызов, сигнал, и каждая пронумерованная ловушка получила символическое имя в Версии 7. kill появился в версии 2, а в версии 5 мог посылать произвольные сигналы. Plan 9 от Bell Labs заменил сигналы заметками, которые позволяют отправлять короткие, произвольные строки.

Отправка сигналов

Системный вызов kill (2) отправляет указанный сигнал указанному процессу, если позволяют разрешения. Точно так же команда kill (1) позволяет пользователю отправлять сигналы процессам. Библиотечная функция raise (3) отправляет указанный сигнал текущему процессу.

Исключения, такие как деление на ноль или нарушение сегментации, будут генерировать сигналы (здесь SIGFPE «исключение с плавающей запятой» и SIGSEGV «нарушение сегментации» соответственно, которые по умолчанию вызывают дамп ядра и выход из программы).

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

Ввод определенных комбинаций клавиш на управляющем терминале запущенного процесса заставляет систему отправлять ему определенные сигналы:

  • Ctrl-C (в старых версиях Unix, DEL) отправляет сигнал INT («прерывание», SIGINT); по умолчанию это приводит к завершению процесса.
  • Ctrl-Z отправляет сигнал TSTP («терминальная остановка», SIGTSTP ); по умолчанию это приводит к приостановке выполнения процесса.
  • Ctrl- \ отправляет сигнал QUIT (SIGQUIT); по умолчанию это приводит к завершению процесса и дампу ядра.
  • (не поддерживается во всех UNIX) отправляет сигнал INFO (SIGINFO); по умолчанию, и если это поддерживается командой, это заставляет операционную систему отображать информацию о запущенной команде.

Эти комбинации клавиш по умолчанию в современных операционных системах можно изменить с помощью команды stty.

Обработка сигналов

Обработчики сигналов могут быть установлены с помощью системного вызова signal (2) или sigaction (2). Если обработчик сигнала не установлен для определенного сигнала, используется обработчик по умолчанию. В противном случае сигнал перехватывается, и вызывается обработчик сигнала. Процесс также может указать два поведения по умолчанию без создания обработчика: игнорировать сигнал (SIG_IGN) и использовать обработчик сигнала по умолчанию (SIG_DFL). Есть два сигнала, которые нельзя перехватить и обработать: SIGKILL и SIGSTOP.

Риски

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

Вызов sigprocmask (2) может использоваться для блокировки и разблокировки доставки сигналов. Заблокированные сигналы не доставляются в процесс, пока не будут разблокированы. Сигналы, которые нельзя игнорировать (SIGKILL и SIGSTOP), нельзя заблокировать.

Сигналы могут вызывать прерывание текущего системного вызова, оставляя управление непрозрачным перезапуском.

Обработчики сигналов должны быть написаны таким образом, чтобы это не приводило к нежелательные побочные эффекты, например изменение ошибки, изменение маски сигнала, изменение расположения сигнала и другие изменения атрибутов глобального процесса . Использование не реентерабельных функций, например, malloc или printf, внутри обработчиков сигналов также небезопасно. В частности, спецификация POSIX и справочная страница Linux signal (7) требуют, чтобы все системные функции, прямо или косвенно вызываемые из сигнальной функции, были безопасными для асинхронных сигналов. signal-safety (7) дает список таких функций системы async-signal safe (практически системные вызовы ), в противном случае это неопределенное поведение. Предлагается просто установить некоторую volatile sig_atomic_tпеременную в обработчике сигнала и протестировать ее где-нибудь еще.

Обработчики сигналов могут вместо этого поместить сигнал в очередь и немедленно вернуться. Затем основной поток будет продолжать "непрерывно" до тех пор, пока из очереди не будут приняты сигналы, например, в цикле событий . «Непрерывный» здесь означает, что операции, которые блок могут вернуться преждевременно, а должны быть возобновлены, как упомянуто выше. Сигналы должны обрабатываться из очереди в основном потоке, а не рабочими пулами, так как это вновь вызывает проблему асинхронности. Однако управление очередью невозможно безопасным способом с использованием асинхронного сигнала с помощью только sig_atomic_t, поскольку только одиночные чтения и записи в такие переменные гарантированно будут атомарными, а не приращениями или (выборка-и) -декрементами, как если бы быть обязательным для очереди. Таким образом, фактически только один сигнал на обработчик может быть безопасно поставлен в очередь с sig_atomic_t до тех пор, пока он не будет обработан.

Связь с аппаратными исключениями

A Выполнение процесса может привести к генерации аппаратного исключения, например, если процесс пытается разделить на ноль или вызывает ошибка страницы.

В Unix-подобных операционных системах это событие автоматически изменяет контекст процессора , чтобы начать выполнение обработчика исключений kernel . В случае некоторых исключений, таких как сбой страницы, ядро ​​имеет достаточно информации, чтобы полностью обработать само событие и возобновить выполнение процесса.

Другие исключения, однако, ядро ​​не может обрабатывать интеллектуально, и вместо этого оно должно отложить операцию обработки исключения процессу, вызвавшему сбой. Эта отсрочка достигается с помощью механизма сигналов, при котором ядро ​​отправляет процессу сигнал, соответствующий текущему исключению. Например, если процесс предпринял попытку целочисленного деления на ноль на x86 CPU, будет сгенерировано исключение ошибки разделения, и ядро ​​отправит сигнал SIGFPE к процессу.

Аналогичным образом, если процесс попытался получить доступ к адресу памяти за пределами его виртуального адресного пространства, ядро ​​уведомит процесс об этом нарушении с помощью сигнала SIGSEGV. Точное соответствие между именами сигналов и исключениями, очевидно, зависит от ЦП, поскольку типы исключений различаются в зависимости от архитектуры.

Сигналы POSIX

В приведенном ниже списке представлены сигналы, указанные в Single Unix Specification. Все сигналы определены как макроконстанты в заголовочном файле . Имя макроконстанты состоит из префикса «SIG» , за которым следует мнемоническое имя сигнала.

SIGABRT и SIGIOT
Сигналы SIGABRT и SIGIOT отправляются процессу, чтобы сообщить ему отменить, то есть завершить работу. Сигнал обычно инициируется самим процессом, когда он вызывает функцию abort() стандартной библиотеки C, но он может быть отправлен процессу извне. как и любой другой сигнал.
SIGALRM, SIGVTALRM и SIGPROF
Сигналы SIGALRM, SIGVTALRM и SIGPROF отправляются процессу, когда лимит времени, указанный в вызове предыдущего функция настройки сигнала тревоги (например, setitimer) истекает. SIGALRM отправляется по истечении реального или часового времени. SIGVTALRM отправляется по истечении процессорного времени, используемого процессом. SIGPROF отправляется, когда процессорное время, используемое процессом и системой от имени процесса, истекает.
SIGBUS
Сигнал SIGBUS отправляется процессу, когда он вызывает ошибка шины. Условиями, которые приводят к отправке сигнала, являются, например, неправильное выравнивание доступа к памяти или несуществующий физический адрес.
SIGCHLD
Сигнал SIGCHLD отправляется процессу, когда дочерний процесс завершается, прерывается или возобновляется после прерывания. Одним из распространенных способов использования сигнала является указание операционной системе очистить ресурсы, используемые дочерним процессом после его завершения, без явного вызова системного вызова wait .
SIGCONT
Сигнал SIGCONT предписывает операционной системе продолжить (перезапустить) процесс, ранее приостановленный сигналом SIGSTOP или SIGTSTP. Одно из важных применений этого сигнала - в управлении заданиями в оболочке Unix.
SIGFPE
Сигнал SIGFPE отправляется процессу, когда он выполняет ошибочную арифметическую операцию, например как деление на ноль. Это может включать целочисленное деление на ноль и целочисленное переполнение в результате деления (только INT_MIN / -1, INT64_MIN / -1 и% -1 доступны из C).
SIGHUP
The Сигнал SIGHUP отправляется процессу, когда его управляющий терминал закрыт. Первоначально он был разработан для уведомления процесса обрыва последовательной линии (зависания ). В современных системах этот сигнал обычно означает, что управляющий псевдотерминал или виртуальный терминал был закрыт. Многие демоны перезагружают свои файлы конфигурации и повторно открывают свои файлы журналов вместо выхода при получении этого сигнала. nohup - это команда, заставляющая команду игнорировать сигнал.
SIGILL
Сигнал SIGILL отправляется процессу, когда он пытается выполнить недопустимую, неверно сформированную, неизвестную или привилегированную инструкцию.
SIGINT
Отправляется сигнал SIGINT к процессу через его управляющий терминал, когда пользователь хочет прервать процесс. Обычно это инициируется нажатием Ctrl+C, но в некоторых системах можно использовать символ «удалить » или «break ».
SIGKILL
Сигнал SIGKILL отправляется процессу, чтобы вызвать его немедленное завершение (kill ). В отличие от SIGTERM и SIGINT, этот сигнал нельзя перехватить или проигнорировать, и принимающий процесс не может выполнить какую-либо очистку после получения этого сигнала. Применяются следующие исключения:
SIGKILL используется как последнее средство при завершении процессов в большинстве системных процедур shutdown, если они не выходит добровольно в ответ на SIGTERM. Чтобы ускорить процедуру выключения компьютера, Mac OS X 10.6, также известная как Snow Leopard, будет отправлять сигнал SIGKILL приложениям, которые помечены как «чистые», что приводит к более быстрому завершению работы без каких-либо побочных эффектов. Команда killall -9имеет аналогичный, но опасный эффект при выполнении, например. в Linux; он не позволяет программам сохранять несохраненные данные. У него есть другие опции, и без них используется более безопасный сигнал SIGTERM.
SIGPIPE
Сигнал SIGPIPE отправляется процессу, когда он пытается записать в pipe без процесса подключен к другому концу.
SIGPOLL
Сигнал SIGPOLL отправляется, когда событие произошло на явно наблюдаемом файловом дескрипторе. Его эффективное использование приводит к выполнению асинхронных запросов ввода / вывода, поскольку ядро ​​опрашивает дескриптор вместо вызывающего. Он предоставляет альтернативу активному опросу.
SIGRTMIN на SIGRTMAX
Сигналы SIGRTMIN на SIGRTMAX предназначены для использования в определенных пользователем целях. Это сигналы в реальном времени.
SIGQUIT
Сигнал SIGQUIT отправляется процессу его управляющим терминалом, когда пользователь запрашивает, чтобы процесс завершил работу и выполнить дамп ядра.
SIGSEGV
Сигнал SIGSEGV отправляется процессу, когда он делает недопустимую ссылку на виртуальную память или segmentation fault, т.е. когда он выполняет нарушение сегментации .
SIGSTOP
Сигнал SIGSTOP инструктирует операционную систему остановить процесс для последующего возобновления.
SIGSYS
Сигнал SIGSYS отправляется процессу, когда он передает неверный аргумент системному вызову . На практике этот вид сигналов встречается редко, поскольку приложения полагаются на библиотеки (например, libc ), чтобы выполнять их вызов. SIGSYS может быть получен приложениями, нарушающими правила безопасности Linux Seccomp, настроенные для их ограничения.
SIGTERM
Сигнал SIGTERM отправляется процессу для запроса его завершения . В отличие от сигнала SIGKILL, он может быть пойман и интерпретирован или проигнорирован процессом. Это позволяет процессу выполнять корректное завершение, высвобождая ресурсы и сохраняя состояние, если необходимо. SIGINT почти идентичен SIGTERM.
SIGTSTP
Сигнал SIGTSTP отправляется процессу его управляющим терминалом, чтобы запросить его stop (tэминал stop). Обычно он инициируется нажатием клавиш Ctrl+Z. В отличие от SIGSTOP, процесс может зарегистрировать обработчик сигнала для сигнала или проигнорировать его.
SIGTTIN и SIGTTOU
Сигналы SIGTTIN и SIGTTOU отправляются процессу, когда он пытается прочитать в или записать из соответственно из tty в фоновом режиме . Обычно эти сигналы получают только процессы под управлением заданиями ; демоны не имеют управляющих терминалов и, следовательно, никогда не должны получать эти сигналы.
SIGTRAP
Сигнал SIGTRAP отправляется процессу при возникновении исключения (или trap ): условие, о котором отладчик запросил информацию, например, когда выполняется конкретная функция или когда конкретная переменная изменяет значение.
SIGURG
Сигнал SIGURG отправляется процессу, когда сокет имеет срочно или out- внеполосные данные доступны для чтения.
SIGUSR1 и SIGUSR2
Сигналы SIGUSR1 и SIGUSR2 отправляются процессу для индикации определенных пользователем условий .
SIGXCPU
Сигнал SIGXCPU отправляется процессу, когда он израсходовал CPU в течение периода, который превышает определенное заранее заданное пользователем значение.. Прибытие сигнала SIGXCPU дает принимающему процессу возможность быстро сохранить любые промежуточные результаты и корректно завершить работу до того, как операционная система завершит его с помощью сигнала SIGKILL.
SIGXFSZ
Сигнал SIGXFSZ отправляется процессу, когда он увеличивает файл, который превышает максимально допустимый размер.
SIGWINCH
Сигнал SIGWINCH отправляется процессу, когда его управляющий терминал изменяет свой размер (win dow ch ange).

действие по умолчанию

Процесс может определять как обрабатывать входящие сигналы POSIX. Если процесс не определяет поведение для сигнала, то используется обработчик по умолчанию для этого сигнала. В таблице ниже перечислены некоторые действия по умолчанию для POSIX-совместимых систем UNIX, таких как FreeBSD, OpenBSD и Linux.

SignalPortable. номерДействие по умолчаниюОписание
SIGABRT6Завершить (дамп ядра)Сигнал прерывания процесса
SIGALRM14ЗавершитьБудильник
SIGBUSN/AЗавершить (дамп ядра)Доступ к неопределенной части объекта памяти
SIGCHLDН / ДИгнорироватьДочерний процесс завершен, остановлен или продолжен
SIGCONTN/AПродолжитьПродолжить выполнение, если остановлено
SIGFPE8Завершить (дамп ядра)Ошибочная арифметическая операция
SIGHUP1ЗавершитьЗависание
SIGILL4Завершить (дамп ядра)Недопустимая инструкция
SIGINT2ЗавершитьСигнал прерывания от терминала
SIGKILL9ЗавершитьУбить (не может быть пойман или игнорируется)
SIGPIPE13TerminateЗапись в канал, когда некому прочитать
SIGPOLLN/ATerminatePollable event
SIGPROFN/AЗавершитьТаймер профилирования истек
SIGQUIT3Завершить (дамп ядра)Сигнал выхода из терминала
SIGSEGV11Завершить (дамп ядра)Неверная память ссылка
SIGSTOPN/AStopОстановить выполнение (не может быть поймано или проигнорировано)
SIGSYSN / AЗавершить (дамп ядра)Неверный системный вызов
SIGTERM15ЗавершитьСигнал завершения
SIGTRAP5Завершить (дамп ядра)Trap / прерывание точки останова
SIGTSTPN/AStopСигнал остановки терминала
SIGTTINN / AОстановитьФоновый процесс пытается прочитать
SIGTTOUN/AStopФоновый процесс пытается записать
SIGUSR1N/ATerminateПользовательский сигнал 1
SIGUSR2N/ATerminateПользовательский сигнал 2
SIGURGN/AИгнорироватьOut-of-ba nd данные доступны в сокете
SIGVTALRMN/ATerminateСрок действия виртуального таймера истек
SIGXCPUN / AЗавершить (дамп ядра)Превышено ограничение по времени ЦП
SIGXFSZN/AЗавершить (дамп ядра)Превышен предел размера файла
SIGWINCHN/AИгнорироватьРазмер окна терминала изменен
Портативный номер:
Для для большинства сигналов соответствующий номер сигнала определяется реализацией. В этом столбце перечислены числа, указанные в стандарте POSIX.
Объяснение действий:
Завершить - Аномальное завершение процесса. Процесс завершается со всеми последствиями _exit (), за исключением того, что статус, доступный для wait () и waitpid (), указывает на ненормальное завершение заданным сигналом.
Завершить (дамп ядра) - Аномальное завершение процесс. Кроме того, могут произойти определенные реализацией действия по аварийному завершению, такие как создание основного файла.
Игнорировать - игнорировать сигнал.
Стоп - Остановить (не завершить) процесс.
Продолжить - продолжить процесс, если он остановлен; в противном случае игнорируйте сигнал.
Прочие сигналы

Следующие сигналы не указаны в спецификации POSIX. Однако иногда они используются в различных системах.

SIGEMT
Сигнал SIGEMT отправляется процессу, когда возникает эмулятор ловушка.
SIGINFO
Сигнал SIGINFO отправляется процессу при получении запроса состояния (info ) от управляющего терминала.
SIGPWR
Сигнал SIGPWR отправляется процессу, когда в системе возникает сбой питания.
SIGLOST
Сигнал SIGLOST отправляется процессу, когда файловая блокировка потеряна.
SIGSTKFLT
Сигнал SIGSTKFLT отправляется процессу когда сопроцессор обнаруживает stackfault(т. е. выскакивает, когда стек пуст, или нажимает, когда он заполнен). Он определяется, но не используется в Linux, где ошибка стека сопроцессора x87 вместо этого генерирует SIGFPE.
SIGUNUSED
Сигнал SIGUNUSED отправляется процессу при системном вызове с неиспользуемым номером системного вызова. Он является синонимом SIGSYS на большинстве архитектур.
SIGCLD
Сигнал SIGCLD является синонимом SIGCHLD.
См. Также
Ссылки
Внешние ссылки
Последняя правка сделана 2021-06-08 08:31:59
Содержание доступно по лицензии CC BY-SA 3.0 (если не указано иное).
Обратная связь: support@alphapedia.ru
Соглашение
О проекте