С точки зрения пользователя получение процессом сигнала выглядит как возникновение прерывания. Процесс прекращает регулярное исполнение, и управление передается механизму обработки сигнала. По окончании обработки сигнала процесс может возобновить регулярное исполнение. Типы сигналов (их принято задавать номерами, как правило, в диапазоне от 1 до 31 включительно или специальными символьными обозначениями) и способы их возникновения в системе жестко регламентированы.
Процесс может получить сигнал от:
Передачу сигналов процессу в случаях его генерации источниками 2, 3 и 5, т.е., в конечном счете, каким-либо другим процессом, можно рассматривать как реализацию в UNIX сигнальных средств связи, о которых рассказывалось в лекции 4.
Существует три варианта реакции процесса на сигнал:
Изменить реакцию процесса на сигнал можно с помощью специальных системных вызовов, которые мы рассмотрим позже. Реакция на некоторые сигналы не допускает изменения, и они могут быть обработаны только по умолчанию. Так, например, сигнал с номером 9 – SIGKILL обрабатывается только по умолчанию и всегда приводит к завершению процесса.
Важным вопросом при программировании с использованием сигналов является вопрос о сохранении реакции на них при порождении нового процесса или замене его пользовательского контекста. При системном вызове fork() все установленные реакции на сигналы наследуется порожденным процессом.
При системном вызове exec() сохраняются реакции только для тех сигналов, которые игнорировались или обрабатывались по умолчанию. Получение любого сигнала, который до вызова exec() обрабатывался пользователем, приведет к завершению процесса.
Прежде чем продолжить тему сигналов, нам придется подробнее остановиться на иерархии процессов в операционной системе.