Книга: Linux программирование в примерах
10.3.1. Функция signal()
10.3.1. Функция signal()
Действие сигнала изменяется с помощью функции signal()
. Вы можете изменить действие на «игнорировать сигнал», «восстановить для сигнала действие системы по умолчанию» или «вызвать при появлении сигнала мою функцию с номером сигнала в качестве параметра».
Функция, которую вы предоставляете для распоряжения сигналом, называется обработчиком сигнала (или просто обработчиком), а установка ее в соответствующем месте осуществляет перехват (catch) сигнала.
Получив эти сведения, давайте перейдем к API. В заголовочном файле <signal.h>
представлены определения макросов для поддерживаемых сигналов и объявления функций управления сигналами, предоставляемыми стандартом С:
#include <signal.h> /* ISO С */
void (*signal(int signum, void (*func)(int)))(int);
Это объявление для функции signal() почти невозможно прочесть. Поэтому справочная страница GNU/Linux signal(2) определяет ее таким способом:
typedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler);
Теперь это более вразумительно. Тип sighandler_t
является указателем на функцию с возвращаемым типом void
, которая принимает один целый аргумент. Это целое является номером поступающего сигнала.
Функция signal()
принимает номер сигнала в качестве своего первого параметра, а указатель функции (новый обработчик) в качестве своего второго аргумента. Если последний не является указателем функции, он может быть лишь SIG_DEF,
что означает «восстановить действие по умолчанию», либо SIG_IGN
, что означает «игнорировать сигнал».
signal()
изменяет действие для signum
и возвращает предыдущее действие. (Это дает вам возможность восстановить при желании предыдущее действие.) Возвращаемое значение может равняться также SIG_ERR
, что указывает на произошедшую ошибку. (Некоторые сигналы невозможно перехватить или игнорировать; предоставление для них обработчика сигнала или неверный signum
создают эту ошибку.) В табл. 10.1 перечислены сигналы, доступные под GNU/Linux, их числовые значения, действия по умолчанию для каждого, формальный стандарт или современная операционная система, которые их определяют, и смысл каждого.
Таблица 10.1. Сигналы GNU/Linux
Имя | Значение | По умолчанию | Источник | Смысл |
---|---|---|---|---|
SIGHUP |
1 | Term | POSIX | Отсоединение |
SIGINT |
2 | Term | ISO C | Прерывание |
SIGQUIT |
3 | Core | POSIX | Выход |
SIGILL |
4 | Core | ISO C | Недействительная инструкция |
SIGTRAP |
5 | Core | POSIX | Трассировочная ловушка |
SIGABRT |
6 | Core | ISO C | Прекращение |
SIGIOT |
6 | Core | BSD | Ловушка IOT |
SIGBUS |
7 | Core | BSD | Ошибка шины |
SIGFPE |
8 | Core | ISO C | Исключение с плавающей точкой |
SIGKILL |
9 | Term | POSIX | Завершение, неблокируемый |
SIGUSR1 |
10 | Term | POSIX | Сигнал 1 пользователя |
SIGSEGV |
11 | Core | ISO C | Нарушение сегмента |
SIGUSR2 |
12 | Term | POSIX | Сигнал 2 пользователя |
SIGPIPE |
13 | Term | POSIX | Нарушенный канал |
SIGALRM |
14 | Term | POSIX | Аварийные часы |
SIGTERM |
15 | Term | ISO C | Завершение |
SIGSTKFLT |
16 | Term | Linux | Ошибка стека в процессоре (не используется) |
SIGCHLD |
17 | Ignr | POSIX | Изменение статуса порожденного процесса |
SIGCLD |
17 | Ignr | System V | То же, что и SIGCHLD (для совместимости) |
SIGCONT |
18 | POSIX | Продолжить при остановке | |
SIGSTOP |
19 | Stop | POSIX | Стоп, неблокируемый |
SIGTSTP |
20 | Stop | POSIX | Стоп от клавиатуры |
SIGTTIN |
21 | Slop | POSIX | Фоновое чтение от tty |
SIGTTOU |
22 | Stop | POSIX | Фоновая запись в tty |
SIGURG |
23 | Ignr | BSD | Срочный сигнал сокета |
SIGXCPU |
24 | Core | BSD | Превышение предела процессора |
SIGXFSZ |
25 | Core | BSD | Превышение предела размера файла |
SIGVTALRM |
26 | Term | BSD | Виртуальные аварийные часы |
SIGPROF |
27 | Term | BSD | Профилирующие аварийные часы |
SIGWINCH |
28 | Ignr | BSD | Изменение размера окна |
SIGIO |
29 | Term | BSD | Возможен ввод/вывод |
SIGPOLL |
29 | Term | System V | Опрашиваемое событие, то же, что и SIGIO (для совместимости) |
SIGPWR |
30 | Term | System V | Повторный запуск из-за сбоя питания |
SIGSYS |
31 | Core | POSIX | Неверный системный вызов |
Обозначения: Core: Завершить процесс и создать снимок образа процесса Ignr: Игнорировать сигнал Stop: Остановить процесс. Term: Завершить процесс.
Более старые версии оболочки Борна (/bin/sh
) непосредственно связывали с номерами сигналов ловушки (traps), которые являются обработчиками сигналов на уровне оболочки. Таким образом, всесторонне образованному Unix-программисту нужно было знать не только имена сигналов для использования в коде С, но также и соответствующие номера сигналов! POSIX требует, чтобы команда trap
понимала символические имена сигналов (без префикса 'SIG
'), поэтому этого больше не требуется. Однако (главным образом для лучшего разбирательства), мы предоставили эти номера в интересах полноты из-за того, что однажды вам может понадобиться иметь дело со сценарием оболочки, созданным до POSIX, или с древним кодом на С, которые непосредственно используют номера сигналов.
ЗАМЕЧАНИЕ. Для некоторых более новых сигналов, от 16 и выше, соответствующие номера сигнала и их имена на различных платформах не обязательно совпадают! Проверьте заголовочные файлы и справочные страницы на своей системе. Табл. 10.1 верна для GNU/Linux
Некоторые системы определяют также и другие сигналы, такие, как SIGEMT
, SIGLOST
и SIGINFO
. Справочная страница GNU/Linux signal(7) предоставляет полный список; если ваша программа должна обработать сигналы, не поддерживаемые GNU/Linux, это можно сделать с помощью #ifdef
:
#ifdef SIGLOST
/* ...обработать здесь SIGLOST... */
#endif
За исключением SIGSTKFLT
, сигналы, перечисленные в табл. 10.1, широкодоступны и не нуждаются в заключении в #ifdef
.
Сигналы SIGKILL
и SIGSTOP
нельзя перехватить или игнорировать (или блокировать, как описано далее в главе). Они всегда выполняют действие по умолчанию, указанное в табл. 10.1.
Чтобы увидеть список поддерживаемых сигналов, вы можете использовать 'kill -l
'. На одной из наших систем GNU/Linux:
$ kill -l
1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL
5) SIGTRAP 6) SIGABRT 7) SIGBUS 8) SIGFPE
9) SIGKILL 10) SIGUSR1 11) SIGSEGV 12) SIGUSR2
13) SIGPIPE 14) SIGALRM 15) SIGTERM 17) SIGCHLD
18) SIGCONT 19) SIGSTOP 20) SIGTSTP 21) SIGTTIN
22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ
26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO
30) SIGPWR 31) SIGSYS 32) SIGRTMIN 33) SIGRTMIN+1
34) SIGRTMIN+2 35) SIGRTMIN+3 36) SIGRTMIN+4 37) SIGRTMIN+5
38) SIGRTMIN+6 39) SIGRTMIN+7 40) SIGRTMIN+8 41) SIGRTMIN+9
42) SIGRTMIN+10 43) SIGRTMIN+11 44) SIGRTMIN+12 45) SIGRTMIN+13
46) SIGRTMIN+14 47) SIGRTMIN+15 48) SIGRTMAX-15 49) SIGRTMAX-14
50) SIGRTMAX-13 51) SIGRTMAX-12 52) SIGRTMAX-11 53) SIGRTMAX-10
54) SIGRTMAX-9 55) SIGRTMAX-8 56) SIGRTMAX-7 57) SIGRTMAX-6
58) SIGRTMAX-5 59) SIGRTMAX-4 60) SIGRTMAX-3 61) SIGRTMAX-2
62) SIGRTMAX-1 63) SIGRTMAX
Сигналы SIGRTXXX
являются сигналами реального времени, сложная тема, которую мы не будем рассматривать.
- 10.3. Стандартные сигналы С: signal() и raise()
- Функция sem_wait
- Функция signal_rt
- Функция signal
- 10.6.4. Перехват сигналов: sigaction()
- Сигналы
- 10.3.2. Программная отправка сигналов: raise()
- 10.4.2. BSD и GNU
- Надежные сигналы
- Состояния дежурного ожидания
- Приложение В Таблица сигналов
- Ждущие блокировки