Основы операционных систем. Практикум

       

Системный вызов signal(). Установка собственного обработчика сигнала


Одним из способов изменения поведения процесса при получении сигнала в операционной системе UNIX является использование системного вызова signal().

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

Прототип системного вызова

#include <signal.h> void (*signal (int sig, void (*handler) (int)))(int);

Описание системного вызова

Системный вызов signal служит для изменения реакции процесса на какой-либо сигнал. Хотя прототип системного вызова выглядит довольно пугающе, ничего страшного в нем нет. Приведенное выше описание можно словесно изложить следующим образом:

функция signal, возвращающая указатель на функцию с одним параметром типа int, которая ничего не возвращает, и имеющая два параметра: параметр sig типа int и параметр handler, служащий указателем на ничего не возвращающую функцию с одним параметром типа int.

Параметр sig – это номер сигнала, обработку которого предстоит изменить.

Параметр handler описывает новый способ обработки сигнала – это может быть указатель на пользовательскую функцию – обработчик сигнала, специальное значение SIG_DFL или специальное значение SIG_IGN. Специальное значение SIG_IGN используется для того, чтобы процесс игнорировал поступившие сигналы с номером sig, специальное значение SIG_DFL – для восстановления реакции процесса на этот сигнал по умолчанию.

Возвращаемое значение

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

Этот системный вызов имеет два параметра: один из них задает номер сигнала, реакцию процесса на который требуется изменить, а второй определяет, как именно мы собираемся ее менять. Для первого варианта реакции процесса на сигнал (см. раздел "Понятие сигнала. Способы возникновения сигналов и виды их обработки") – его игнорирования – применяется специальное значение этого параметра SIG_IGN. Например, если требуется игнорировать сигнал SIGINT, начиная с некоторого места работы программы, в этом месте программы мы должны употребить конструкцию

(void) signal(SIGINT, SIG_IGN);

Для второго варианта реакции процесса на сигнал – восстановления его обработки по умолчанию – применяется специальное значение этого параметра SIG_DFL. Для третьего варианта реакции процесса на сигнал в качестве значения параметра подставляется указатель на пользовательскую функцию обработки сигнала, которая должна иметь прототип вида

void *handler(int);

Ниже приведен пример скелета конструкции для пользовательской обработки сигнала SIGHUP.

void *my_handler(int nsig) { <обработка сигнала> } int main() { ... (void)signal(SIGHUP, my_handler); ... }

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



Содержание раздела