Сигналы являются программными прерываниями, которые посылаются процессу,
когда случается некоторое событие. Сигналы могут возникать синхронно
с ошибкой в приложении, например SIGFPE(ошибка вычислений с плавающей
запятой) и SIGSEGV(ошибка адресации), но большинство сигналов является
асинхронными. Сигналы могут посылаться процессу, когда система обнаруживает
программное событие, например, когда пользователь дает команду прервать
или остановить выполнение, или сигнал на завершение от другого процесса.
Сигналы могут прийти непосредственно от ядра ОС, когда возникает сбой
аппаратных средств ЭВМ. Система определяет набор сигналов, которые
могут быть отправлены процессу. В Linux существует примерно 30 различных
сигналов. При этом каждый сигнал имеет целочисленное значение и приводит
к строго определенным действиям.
Механизм передачи сигналов состоит из следующих частей:
Установление и обозначение сигналов в форме целочисленных значений
Маркер в строке таблицы процессов для прибывших сигналов
Таблица с адресами функций, которые определяют реакцию на прибывающие
сигналы.
Отдельные сигналы разделяются на три различных класса:
Системные сигналы (ошибка аппаратуры, системная ошибка и т.д.)
Сигналы от устройств
Определенные пользователем сигналы
Как только сигнал приходит, он отмечается записью в таблице процессов.
Если этот сигнал определен для процесса, то по таблице указателей
функций в структуре Task определяется, как нужно реагировать на этот
сигнал. При этом номер сигнала служит индексом таблицы.
Существует три основных варианта реакции на сигналы:
вызов собственной функции обработки;
игнорирование сигнала (не работает для SIGKILL);
использование предварительно установленной функции обработки по умолчанию.
Чтобы реагировать на те или другие сигналы, необходимо понимать концепции
обработки сигнала. Процесс должен организовать так называемый обработчик
сигнала. Эти обработчики срабатывают в случае прихода сигнала. Для
этого используется функция signal().
signr устанавливает номер сигнала, для которого устанавливается
обработчик. В заголовочном файле <signal.h> определены следующие
сигналы (табл. 1).
Табл. 1. Сигналы ОС Linux.
Номер
Значение
Реакция программы по умолчанию
Переменная sighandler определяет функцию обработки сигнала.
В заголовочном файле <signal.h> определены две константы
SIG_DFL и SIG_IGN. SIG_DFL означает
выполнение действий по умолчанию - в большинстве случаев окончание
процесса. Например, определение
signal(SIGINT,SIG_DFL);
приведет к тому, что при нажатии на комбинацию клавиш CTRL+C
во время выполнения сработает реакция по умолчанию на сигнал SIGINT
и программа завершится. С другой стороны, можно определить
signal(SIGINT, SIG_IGN);
Если теперь нажать на комбинацию клавиш CTRL+C, ничего не
произойдет, так как сигнал SIGINT игнорируется. Третьим способом
является перехват сигнала SIGINT и передача управления на
адрес собственной функции, которая должна выполнять действия, если
была нажата комбинация клавиш CTRL+C, например...
signal(SIGINT, function);
Пример использования обработчика сигнала (рис. 6):
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
void sigfunc(int sig)
{
char c;
if(sig != SIGINT)
return;
else
{
printf("\nХотите завершить программу (y/n) : ");
while((c=getchar()) != 'n')
return;
exit (0);
}
}
int main()
{
int i;
signal(SIGINT,sigfunc);
while(1)
{
printf(" Вы можете завершить программу с помощью CTRL+C ");