Установить способ обработки (или обработчик) исключительных событий
#include <signal.h>void (* signal( int sig,void (*func)( int ) ))( int );
<signal.h>
). Для получения более подробной информации см. Сигналы POSIX в документации к SignalAction().libc
Функция signal() используется для указания действия, которое должно выполниться при обнаружении определенных условий во время выполнения программы. Определения этих условий см. в заголовочном файле <signal.h>
.
Существует три типа действий, которые могут быть связаны с сигналом: SIG_DFL
, SIG_IGN
или указатель на функцию. Первоначально все сигналы устанавливаются в SIG_DFL
или SIG_IGN
перед входом в процедуру main(). Действие может быть указано для каждого из условий, в зависимости от значения аргумента func, как описано ниже.
Если func – указатель на функцию
Если func является функцией, то вызывается она следующим способом:
/* "sig_no" is condition being signalled */signal( sig_no, SIG_DFL );(*func)( sig_no );
Функция func может сделать следующее:
Небезопасно использовать операции с плавающей запятой в обработчиках сигналов. |
После возврата из функции захвата сигнала, принимающий процесс возобновляет выполнение с того места, на котором оно было прервано.
Функция захвата сигнала описывается следующим образом:
void func( int sig_no ){...}
Невозможно перехватить сигналы SIGSTOP
или SIGKILL
.
Поскольку функции захвата сигналов вызываются асинхронно с выполнением процесса, необходимо учитывать то же, что и в многопоточной программе при проверке или манипулировании разделяемыми ресурсами.
Если func – SIG_DFL
Если func есть SIG_DFL
, то выполняется действие по умолчанию для данного сигнала.
Если действием по умолчанию является остановка процесса, выполнение этого процесса временно приостанавливается. Когда процесс останавливается, для его родительского процесса генерируется сигнал SIGCHLD
, если родительский процесс не установил флаг SA_NOCLDSTOP
(см. sigaction()). Когда процесс остановлен, любые дополнительные сигналы, отправленные процессу, не доставляются до тех пор, пока процесс не продолжит исполнение, за исключением SIGKILL
, который всегда завершает принимающий процесс.
Установка действия сигнала на SIG_DFL
для ожидающего сигнала, действие которого по умолчанию — игнорировать сигнал (например, SIGCHLD
), приводит к тому, что ожидающий сигнал отбрасывается независимо от того, заблокирован он или нет.
Если func – SIG_IGN
Если func есть SIG_IGN
, указанный сигнал игнорируется.
Невозможно установить действие для сигналов SIGSTOP
и SIGKILL
на SIG_IGN
.
Установка действия сигнала на SIG_IGN
для ожидающего сигнала приводит к тому, что ожидающий сигнал отбрасывается, независимо от того, заблокирован он или нет.
Если процесс устанавливает действие для сигнала SIGCHLD
на SIG_IGN
, его потомки не перейдут в состояние "зомби", и процесс не сможет использовать wait() или waitpid() для ожидания их "смерти".
Обработка
Когда событие обнаружено, оно может быть обработано программой, может быть проигнорировано или может быть обработано по умолчанию (часто вызывая печать сообщения об ошибке в поток stderr с последующим завершением программы).
Условие может быть сгенерировано программой с помощью функции raise() или kill().
Предыдущее значение func для указанного условия или SIG_ERR
, если запрос не может быть обработан ( errno устанавливается в EINVAL
).
#include <stdlib.h>#include <signal.h>sig_atomic_t signal_count;void MyHandler( int sig_number ){++signal_count;}int main( void ){signal( SIGFPE, MyHandler ); /* set own handler */signal( SIGABRT, SIG_DFL ); /* Default action */signal( SIGFPE, SIG_IGN ); /* Ignore condition */return (EXIT_SUCCESS);}
ANSI, POSIX 1003.1
atomic_add(), atomic_add_value(), atomic_clr(), atomic_clr_value(), atomic_set(), atomic_set_value(), atomic_sub(), atomic_sub_value(), atomic_toggle(), atomic_toggle_value(), kill(), longjmp(), pthread_sigmask(), raise(), SignalAction(), siglongjmp(), sigprocmask()
Предыдущий раздел: Описание API системной библиотеки