Сигналы

Сигнал – средство уведомления процесса о наступлении некоторого события в системе.

Инициаторы посылки сигнала - другой процесс или ОС.

Сигнал- программный аналог прерывания.

Количество различных сигналов в современных версиях UNIX около 30, каждый из них имеет уникальное имя и номер. Описания представлены в файле <signal.h>. Ниже приведено несколько примеров.

2 - SIGINT /*прерывание*/

3 - SIGQUIT /*аварийный выход*/

9 - SIGKILL /*уничтожение процесса*/

14 - SIGALRM /*прерывание от таймера*/.

18 - SIGCHLD /*процесс-потомок завершился*/.


В разных версиях UNIX имена сигналов могут различаться.

Сигналы, посылаемые ОС, уведомляют о наступлении некоторых строго предопределенных ситуаций (как, например, завершение порожденного процесса, прерывание процесса нажатием комбинации Ctrl-C, попытка выполнить недопустимую машинную инструкцию, попытка недопустимой записи в канал и т.п.), при этом каждой такой ситуации сопоставлен свой сигнал. Кроме того, зарезервировано один или несколько номеров сигналов, семантика которых определяется пользовательскими процессами по своему усмотрению (например, процессы могут посылать друг другу сигналы с целью синхронизации).

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

При получении сигнала процессом возможны три варианта реакции на полученный сигнал:

- Процесс реагирует на сигнал стандартным образом, установленным по умолчанию (для большинства сигналов действие по умолчанию – это завершение процесса).

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

- Процесс может проигнорировать сигнал.

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

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

Отдельного рассмотрения заслуживает ситуация, когда сигнал приходит в момент выполнения системного вызова. Обработка такой ситуации в разных версиях UNIX реализована по-разному, например, обработка сигнала может быть отложена до завершения системного вызова; либо системный вызов автоматически перезапускается после его прерывания сигналом; либо системный вызов вернет –1, а в переменной errno будет установлено значение EINTR

Системный вызов kill()

Для отправки сигнала существует системный вызов kill():

#include <signal.h>

int kill (pit_t pid, int sig);

pid – идентификатор процесса, которому посылается сигнал

Существует также возможность одновременно послать сигнал нескольким процессам, например, если значение этого параметра есть 0, сигнал будет передан всем процессам, которые принадлежат той же группе, что и процесс, посылающий сигнал, за исключением процессов с идентификаторами 0 и 1.

sig – номер посылаемого сигнала

Если этот параметр равен 0, то будет выполнена проверка корректности обращения к kill(), но никакой сигнал в действительности посылаться не будет.

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

При удачном выполнении возвращает 0, в противном случае возвращает –1

Системный вызов signal()

Для определения реакции на получение того или иного сигнала в процессе служит системный вызов signal():

#include <signal.h>

void (*signal (int sig, void (*disp) (int))) (int);

sig – номер сигнала, для которого устанавливается реакция

disp – либо определенная пользователем функция – обработчик сигнала, либо одна из констант:

SIG_DFL - обработка по умолчанию

SIG_IGN - игнорирование

При успешном завершении функция возвращает указатель на предыдущий обработчик данного сигнала.


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: