Функции библиотеки C -sigaction()
Стандартная библиотека C - <signal.h>
sigactionЭта функция — функция стандартной библиотеки C, используемая для проверки или изменения действия обработки, связанного с конкретным сигналом. СsignalПо сравнению с функцией,sigactionОбеспечивает больше контроля и лучшую переносимость.
Синтаксис
int sigaction(int sig, const struct sigaction *act, struct sigaction *oldact);
Параметр
int sig: номер сигнала для проверки или изменения. Обычные сигналы включаютSIGINT、SIGTERM、SIGKILLи т. д.const struct sigaction *act: указатель на новое действие обработки сигнала. Если он равенNULL, текущее действие обработки сигнала не изменяется.struct sigaction *oldact: указатель для сохранения старого действия обработки сигнала. Если он равенNULL, старое действие обработки сигнала не сохраняется.
struct sigactionСтруктура
struct sigaction {
void (*sa_handler)(int); // 信号处理函数指针
void (*sa_sigaction)(int, siginfo_t *, void *); // 信号处理函数指针(扩展)
sigset_t sa_mask; // 在处理该信号时要阻塞的信号集
int sa_flags; // 修改信号行为的选项
void (*sa_restorer)(void); // 恢复函数,已废弃
};
sa_flagsобщие параметры
SA_RESTART: Автоматически перезапускать системные вызовы, прерванные сигналом.SA_SIGINFO: Использоватьsa_sigactionвместоsa_handlerв качестве функции обработки сигнала.SA_NOCLDSTOP: еслиsigДаSIGCHLD, сигнал не генерируется, когда дочерний процесс останавливается или возобновляется.
Возвращаемое значение
- Возвращает 0 при успехе.
- При ошибке возвращает -1 и устанавливает
errnoдля указания типа ошибки.
Пример
Ниже приведён простой пример программы, демонстрирующий, как использоватьsigactionНастройки функцииSIGINTОбработчик сигнала:
Пример
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
// Пользовательская функция обработки сигнала
void handle_sigint(int sig) {
printf("Перехвачен сигнал %d\n", sig);
}
int main() {
struct sigaction sa;
// Установить обработчик handle_sigint
sa.sa_handler = handle_sigint;
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;
// Использовать sigaction для установки нового действия обработки сигнала
if (sigaction(SIGINT, &sa, NULL) == -1) {
perror("sigaction");
return 1;
}
// Основной цикл, продолжает выполняться, пока не будет перехвачен сигнал
while (1) {
printf("Выполняется...\n");
sleep(1);
}
return 0;
}
#include <signal.h>
#include <unistd.h>
// Пользовательская функция обработки сигнала
void handle_sigint(int sig) {
printf("Перехвачен сигнал %d\n", sig);
}
int main() {
struct sigaction sa;
// Установить обработчик handle_sigint
sa.sa_handler = handle_sigint;
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;
// Использовать sigaction для установки нового действия обработки сигнала
if (sigaction(SIGINT, &sa, NULL) == -1) {
perror("sigaction");
return 1;
}
// Основной цикл, продолжает выполняться, пока не будет перехвачен сигнал
while (1) {
printf("Выполняется...\n");
sleep(1);
}
return 0;
}
После компиляции и запуска программы вывод будет следующим:
Running... Running... Running... ...
При нажатии Ctrl+C (отправкаSIGINTсигнала), вывод будет:
Caught signal 2
Программа перехватилаSIGINTсигнал и выполнила пользовательскую функцию обработки сигналаhandle_sigint, а затем продолжила выполнение основного цикла.
Примечания
sigactionФункция предоставляет больше, чемsignalФункция предоставляет более богатую функциональность, позволяя задавать обработчики сигналов, маски сигналов и параметры обработки сигналов.- Функция обработки сигнала должна быть как можно короче, потому что во время обработки сигнала другие сигналы блокируются. Если функция обработки сигнала выполняется слишком долго, это может повлиять на производительность программы в реальном времени.
- Некоторые сигналы (такие как
SIGKILLиSIGSTOP) невозможно перехватить или игнорировать.