В вычислениях, sigaction
- это API-интерфейс функции, определенный в POSIX, чтобы дать программисту доступ к тому, каким должно быть поведение программы при получении определенных сигналов ОС .
В В Unix-подобных операционных системах одним из средств межпроцессного взаимодействия является передача сигналов. Когда исполняющий модуль (процесс или поток ) получает сигнал из ОС, он должен реагировать некоторым образом, определяемым d аташит и условное значение этого сигнала (т. е. путем сброса данных, остановки выполнения, синхронизации чего-либо...).
Системный вызов sigaction ()
используется для объявления поведения программы, если она получит один конкретный сигнал, не зарезервированный системой. Это делается путем предоставления вместе с системным вызовом структуры, содержащей, среди прочего, указатель функции на подпрограмму обработки сигнала. Некоторые предопределенные сигналы (например, SIGKILL
) имеют заблокированное поведение, которое обрабатывается системой и не может быть отменено такими системными вызовами.
Стандарт POSIX требует, чтобы структура sigaction была определена, как показано ниже, в файле заголовка
struct sigaction {void (* sa_handler) (число); / * адрес обработчика сигнала * / sigset_t sa_mask; / * дополнительные сигналы для блокировки * / int sa_flags; / * параметры сигнала * / / * альтернативный обработчик сигнала * / void (* sa_sigaction) (int, siginfo_t *, void *); };
Реализации могут определять дополнительные, возможно, непереносимые поля. Член sa_handler указывает адрес функции, которая должна быть вызвана, когда процесс получает сигнал. Номер сигнала передается в эту функцию как целочисленный аргумент. Член sa_mask указывает дополнительные сигналы, которые должны быть заблокированы во время выполнения обработчика сигналов. sa_mask необходимо инициализировать с помощью sigemptyset (3). Член sa_flags определяет некоторые дополнительные флаги. sa_sigaction - это альтернативный обработчик сигналов с другим набором параметров. Должен быть указан только один обработчик сигнала: sa_handler или sa_sigaction. Если желательно использовать sa_sigaction вместо sa_handler, необходимо установить флаг SA_SIGINFO.
signal()
Функция sigaction ()
предоставляет интерфейс для надежных сигналов вместо ненадежного и устаревшего сигнала ()
функция. Обработчики сигналов, установленные интерфейсом signal ()
, будут удалены непосредственно перед выполнением обработчика. Поэтому постоянные обработчики должны быть переустановлены путем вызова signal ()
во время выполнения обработчика, что вызывает ненадежность в случае, если сигнал того же типа получен во время выполнения обработчика, но до переустановки. Обработчики, установленные интерфейсом sigaction ()
, могут быть установлены постоянно, а пользовательский набор сигналов может быть заблокирован во время выполнения обработчика. Эти сигналы будут разблокированы сразу после нормального завершения работы обработчика (но не в случае аварийного завершения, такого как выброс исключения C ++.)
В C ++ try {/ *... * /} catch {/ *... * /}
структура программирования может (в зависимости от хост-платформ) основываться на сигнализации. Для перехвата сигналов
, преобразованных в исключения C ++, на некоторых платформах могут потребоваться специальные переключатели компилятора, такие как -fnon-call-exceptions
для GCC и компилятор Intel C..
#include#include #include #include #include #include #define NUMCHLDS 10 void sigchld_handler (int, siginfo_t *, недействительно *); sig_atomic_t nexitedchlds = 0; int main (int argc, char * argv) {struct sigaction act; memset (act, 0, sizeof (struct sigaction)); sigemptyset (act.sa_mask); act.sa_sigaction = sigchld_handler; act.sa_flags = SA_SIGINFO; если (-1 == sigaction (SIGCHLD, act, NULL)) {ошибка ("sigaction ()"); выход (EXIT_FAILURE); } for (int i = 0; i < NUMCHLDS; i++) { switch(fork()) { case 0: /* * Older OS implementations that do not correctly implement * the siginfo structure will truncate the exit code * by masking it with 0xFF. */ return 1234567890; /* NOTREACHED */ case -1: write(STDERR_FILENO, "fork ERROR!", 11); exit(EXIT_FAILURE); /* NOTREACHED */ default: printf("Child created\n"); } } while (1) { if (nexitedchlds < NUMCHLDS) pause(); else exit(EXIT_SUCCESS); } /* NOTREACHED */ return 0; } void sigchld_handler(int signo, siginfo_t *sinfo, void *context) { pid_t proc; while ((proc = waitpid(-1, NULL, WNOHANG))>0) {/ * основной поток сигнала * / nexitedchlds ++; / * * примечание: printf () небезопасен для сигналов! * не используйте его в обработчике сигналов. * si_code - это полный 32-битный код выхода дочернего объекта (см. также waitid ()). * / printf ("sinfo->si_pid =% ld \ nproc =% ld \ nexit code% d причина выхода% d \ n", (long) sinfo->si_pid, (long) proc, sinfo->si_status, sinfo->si_code); }}
sigaction
: изучить и изменить действие сигнала - Справочник по системным интерфейсам, Единая спецификация UNIX, выпуск 7 из Открытая группа