Стандартная библиотека C -<signal.h>
Введение
<signal.h>Это заголовочный файл в стандартной библиотеке C, используемый для обработки сигналов.
signal.hЗаголовочный файл определяет тип переменнойsig_atomic_tдва вызова функций и некоторые макросы для обработки различных сигналов, сообщаемых во время выполнения программы.
Сигнал — это механизм асинхронного уведомления, который позволяет процессу выполнить предопределённую функцию-обработчик при возникновении определённого события.
Ниже приведён простой пример программы, демонстрирующий использование функции signal для перехвата сигнала SIGINT (обычно генерируемого нажатием Ctrl+C).
Пример
#include <signal.h>
#include <unistd.h>
// Глобальная переменная, указывающая, должна ли программа завершиться
volatile sig_atomic_t stop = 0;
void handle_sigint(int sig) {
printf("Перехвачен сигнал %d\n", sig);
stop = 1; // Установить флаг завершения
}
int main() {
// Установить обработчик для сигнала SIGINT в функцию handle_sigint
signal(SIGINT, handle_sigint);
while (!stop) { // Проверить, нужно ли завершаться
printf("Выполняется...\n");
sleep(1);
}
printf("Выход...\n");
return 0;
}
В приведённом выше коде, когда программа выполняется, если пользователь нажмётCtrl+C, она перехватит сигнал SIGINT и вызовет функцию handle_sigint, напечатав номер сигнала.
Скомпилируйте и выполните приведённый выше код, вывод будет следующим:
Running... Running... Running... ^CCaught signal 2 Exiting...
Анализ кода:
volatile sig_atomic_t stop = 0;: определите глобальную переменнуюstop, используется для указания, должна ли программа завершиться. Использованиеvolatileключевое слово гарантирует, что компилятор не удалит обращения к этой переменной в результате оптимизации, потому что она может быть изменена в обработчике сигнала.sig_atomic_tТип гарантирует, что обращения к этой переменной являются атомарными.- В
handle_sigintВ функции обработчика сигнала установитеstopв 1, указывая, что программа должна завершиться. - В основном цикле проверьте
stopзначение переменной; если оно установлено в 1, выйдите из цикла и завершите программу.
Переменные библиотеки
Ниже приведены типы переменных, определённые в заголовочном файле signal.h:
| Порядковый номер | Переменные и описание |
|---|---|
| 1 | sig_atomic_t Этоint-тип, используемый как переменная в обработчиках сигналов. Это целочисленный тип объекта, к которому можно обращаться как к атомарной сущности даже при наличии асинхронных сигналов. |
| 2 | sigset_t Тип данных, используемый для представления набора сигналов. |
Библиотечные макросы
<В стандартной библиотеке C,SIG_Префиксные макросы иsignalИспользуются вместе с функциями для определения и обработки поведения сигналов. Ниже приведены распространённыеSIG_Макросы и их назначение:
| Порядковый номер | Макросы и описание |
|---|---|
| 1 | SIG_DFL Представляет обработчик сигнала по умолчанию. Используйте этот макрос, чтобы восстановить поведение сигнала по умолчанию. |
| 2 | SIG_ERR Представляет возвращаемое значение при ошибке установки функции обработчика сигнала. |
| 3 | SIG_IGN Игнорировать сигнал. |
Типы сигналов:
| Константы | Описание |
|---|---|
SIGABRT | отabortСигнал, сгенерированный функцией, указывающий на аварийное завершение |
SIGALRM | отalarmСигнал истечения таймера, установленный функцией |
SIGBUS | Недопустимый доступ к памяти (например, доступ к невыровненному адресу памяти) |
SIGCHLD | Статус дочернего процесса изменился (завершился или остановился) |
SIGCONT | Продолжить выполнение приостановленного процесса |
SIGFPE | Арифметические ошибки (например, деление на ноль, исключения с плавающей запятой) |
SIGHUP | Сигнал разрыва (обычно используется для обнаружения отключения терминала) |
SIGILL | Недопустимая инструкция |
SIGINT | Сигнал прерывания (обычно генерируется нажатием Ctrl+C) |
SIGKILL | Сигнал немедленного завершения (не может быть перехвачен или проигнорирован) |
SIGPIPE | Запись данных в канал при отсутствии читающего процесса |
SIGQUIT | Сигнал завершения терминала (обычно генерируется Ctrl+\), создаёт дамп памяти |
SIGSEGV | Ошибка сегментации (недопустимый доступ к памяти) |
SIGSTOP | Останавливает выполнение процесса (не может быть перехвачен или проигнорирован) |
SIGTERM | Сигнал завершения |
SIGTSTP | Приостанавливает процесс (обычно генерируется Ctrl+Z) |
SIGTTIN | Сигнал, генерируемый, когда фоновый процесс читает данные из терминала |
SIGTTOU | Сигнал, генерируемый, когда фоновый процесс записывает данные в терминал |
SIGUSR1 | Пользовательский сигнал 1 |
SIGUSR2 | Пользовательский сигнал 2 |
SIGPOLL | Событие ввода-вывода (заменяет SIGIO) |
SIGPROF | Сигнал истечения таймера (отsetitimerустановленного таймера профилирования) |
SIGSYS | Недопустимый системный вызов |
SIGTRAP | Точка останова или инструкция-ловушка |
SIGURG | Сигнал срочного состояния сокета |
SIGVTALRM | Сигнал истечения таймера виртуального времени |
SIGXCPU | Превышен лимит времени ЦП |
SIGXFSZ | Превышен лимит размера файла |
Библиотечные функции
Ниже приведены функции, определённые в заголовочном файле signal.h:
| Функция | Описание |
|---|---|
void (*signal(int sig, void (*func)(int)))(int); |
Установить обработчик сигнала. |
int raise(int sig); |
Отправить сигнал текущему процессу. |
int kill(pid_t pid, int sig); |
Отправить сигнал указанному процессу. |
int sigprocmask(int how, const sigset_t *set, sigset_t *oldset); |
Проверить или изменить набор заблокированных сигналов. |
int sigaction(int sig, const struct sigaction *act, struct sigaction *oldact); |
Проверить или изменить обработчик сигнала. |
int sigsuspend(const sigset_t *mask); |
Временно заменить текущую маску сигналов и приостановить процесс до перехвата сигнала. |
int sigpending(sigset_t *set); |
Проверить набор ожидающих сигналов. |
int sigemptyset(sigset_t *set); |
Инициализировать набор сигналов пустым набором. |
int sigfillset(sigset_t *set); |
Инициализировать набор сигналов полным набором сигналов. |
int sigaddset(sigset_t *set, int signum); |
Добавить указанный сигнал в набор сигналов. |
int sigdelset(sigset_t *set, int signum); |
Удалить указанный сигнал из набора сигналов. |
int sigismember(const sigset_t *set, int signum); |
Проверить, содержится ли указанный сигнал в наборе сигналов. |
void abort(void); |
raiseSIGABRTСигнал вызывает аварийное завершение процесса. |
unsigned int alarm(unsigned int seconds); |
Через указанное число секунд отправитьSIGALRMсигнал вызывающему процессу. |
int pause(void); |
Приостановить процесс до перехвата сигнала. |
void psignal(int sig, const char *s); |
Вывести информацию с описанием сигнала. |
char *strsignal(int sig); |
Вернуть строку с описанием сигнала. |
int sigwait(const sigset_t *set, int *sig); |
Блокировать в ожидании сигнала и обработать его. |