Сигналы являются программными прерываниями, которые посылаются процессу, когда случается некоторое событие. Сигналы могут возникать синхронно с ошибкой в приложении, например SIGFPE (ошибка вычислений с плавающей запятой) и SIGSEGV (ошибка адресации), но большинство сигналов является асинхронными. Сигналы могут посылаться процессу, если система обнаруживает программное событие, например, когда пользователь дает команду прервать или остановить выполнение, или получен сигнал на завершение от другого процесса. Сигналы могут прийти непосредственно от ядра ОС, когда возникает сбой аппаратных средств ЭВМ. Система определяет набор сигналов, которые могут быть отправлены процессу. В Linux применяется около 30 различных сигналов. При этом каждый сигнал имеет целочисленное значение и приводит к строго определенным действиям.
Механизм передачи сигналов состоит из следующих частей:
Известно три варианта реакции на сигналы:
void(*signal(int signr, void(*sighandler)(int)))(int);
signalfunction *sighandler);
Номер | Значение | Реакция программы по умолчанию |
SIGABRT | Ненормальное завершение (abort()) | Завершение |
SIGALRM | Окончание кванта времени | Завершение |
SIGBUS | Аппаратная ошибка | Завершение |
SIGCHLD | Изменение состояния потомка | Игнорирование |
SIGCONT | Продолжение прерванной программы | Продолжение / игнорирование |
SIGEMT | Аппаратная ошибка | Завершение |
SIGFPE | Ошибка вычислений с плавающей запятой | Завершение |
SIGILL | Неразрешенная аппаратная команда | Завершение |
SIGINT | Прерывание с терминала | Завершение |
SIGIO | Асинхронный ввод/вывод | Игнорирование |
SIGKILL | Завершение программы | Завершение |
SIGPIPE | Запись в канал без чтения | Завершение |
SIGPWR | Сбой питания | Игнорирование |
SIGQUIT | Прерывание с клавиатуры | Завершение |
SIGSEGV | Ошибка адресации | Завершение |
SIGSTOP | Остановка процесса | Остановка |
SIGTTIN | Попытка чтения из фонового процесса | Остановка |
SIGTTOU | Попытка записи в фоновый процесс | Остановка |
SIGUSR1 | Пользовательский сигнал | Завершение |
SIGUSR2 | Пользовательский сигнал | Завершение |
SIGXCPU | Превышение лимита времени CPU | Завершение |
SIGXFSZ | Превышение пространства памяти (4GB) | Завершение |
SIGURG | Срочное событие | Игнорирование |
SIGWINCH | Изменение размера окна | Игнорирование |
Переменная 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);
Пример использования обработчика сигнала приведен ниже:
#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 ");
for(i=0;i<=48;i++)
printf("\b");
}
return 0;
}