Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Конспект Граур.doc
Скачиваний:
59
Добавлен:
14.11.2019
Размер:
3.7 Mб
Скачать

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

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

#include <signal.h>

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

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

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

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

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

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

Пример 1.

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

#include <sys/types.h>

#include <signal.h>

#include <stdio.h>

int count = 0;

void SigHndlr (int s) /* обработчик сигнала */

{ printf("\n I got SIGINT %d time(s) \n",

++ count);

if (count == 5) signal (SIGINT, SIG_DFL);

/* ставим обработчик сигнала по умолчанию */

else signal (SIGINT, SigHndlr);

/* восстанавливаем обработчик сигнала */

}

int main(int argc, char **argv)

{ signal (SIGINT, SigHndlr); /* установка реакции на сигнал */

while (1); /*”тело программы” */

return 0;

}

Пример 2.

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

#include <unistd.h>

#include <signal.h>

#include <sys/types.h>

#include <sys/stat.h>

#include <fcntl.h>

const char * tempfile = “abc”;

void SigHndlr (int s)

{

unlink(tempfile);

/* уничтожение временного файла в случае прихода сигнала SIGINT. В случае, если такой файл не существует (еще не создан или уже удален), вызов вернет -1 */

exit(0);

}

int main(int argc, char **argv)

{

signal (SIGINT, SigHndlr); /*установка реакции на сигнал */

creat(tempfile, 0666); /*создание временного файла*/

unlink(tempfile);

/*уничтожение временного файла в случае нормального функционирования процесса */

return 0;

}

5 Пример. Программа “Будильник”.

Существуют задачи, в которых необходимо прервать выполнение процесса по истечении некоторого количества времени. Средствами ОС “заводится” будильник, который будет поторапливать ввести некоторое имя. Системный вызов alarm():

#include <unistd.h>

unsigned int alarm(unsigned int seconds);

инициализирует отложенное появление сигнала SIGALRM - процесс запрашивает ядро отправить ему самому сигнал по прошествии определенного времени.

#include <unistd.h>

#include <signal.h>

#include <stdio.h>

void alrm(int s) /*обработчик сигнала SIG_ALRM */

{

printf(“\n жду имя \n”);

alarm(5); /* заводим будильник */

signal(SIGALRM, alrm); /* переустанавливаем реакцию на сигнал */

}

int main(int argc, char **argv)

{

char s[80];

signal(SIGALRM, alrm);

/* установка обработчика alrm на приход сигнала SIG_ALRM */

alarm(5); /* заводим будильник */

printf(“Введите имя \n”);

for (;;)

{

printf(“имя:”);

if (gets(s) != NULL) break; /* ожидаем ввода имени */

};

printf(“OK! \n”);

return 0;

}

В начале программы мы устанавливаем реакцию на сигнал SIGALRM - функцию alarm(), далее мы заводим будильник, запрашиваем “Введите имя” и ожидаем ввода строки символов. Если ввод строки задерживается, то будет вызвана функция alarm(), которая напомнит, что программа “ждет имя”, опять заведет будильник и поставит себя на обработку сигнала SIGALRM еще раз. И так будет до тех пор, пока не будет введена строка. Здесь имеется один нюанс: если в момент выполнения системного вызова возникает событие, связанное с сигналом, то система прерывает выполнение системного вызова и возвращает код ответа, равный «-1».