• SA_NOCLDWAIT — (начиная с Linux 2.6) если аргумент sig равен SIGCHILD, не превращать дочерние процессы в «зомби» при завершении. Для получения более подробной информации см. подраздел 26.3.2.

• SA_NODEFER — при перехвате этого сигнала не добавлять его автоматически в сигнальную маску процесса на время выполнения обработчика. Имя SA_NOMASK является историческим синонимом для SA_NODEFER, однако последнее считается предпочтительным, так как оно стандартизировано в SUSv3.

• SA_ONSTACK — активировать обработчик для этого сигнала с использованием альтернативного стека, установленного функцией sigaltstack(). См. раздел 21.3.

• SA_RESETHAND — при перехвате сигнала сбросить его диспозицию до значения по умолчанию (то есть SIG_DFL) перед активацией обработчика. (По умолчанию обработчик остается установленным до тех пор, пока не будет явно отключен следующим вызовом функции sigaction().) Имя SA_ONESHOT является историческим синонимом для SA_RESETHAND, однако последнее считается предпочтительным, так как оно стандартизировано в SUSv3.

• SA_RESTART — автоматически перезапустить системный вызов, прерванный обработчиком сигнала. См. раздел 21.5.

• SA_SIGINFO — активировать обработчик сигнала с дополнительными аргументами, предоставляющими дополнительную информацию о сигнале (см. раздел 21.4).

Все вышеперечисленные параметры определены в стандарте SUSv3. Пример использования функции sigaction() приведен в листинге 21.1.

20.14. Ожидание сигнала: pause()

Вызов функции pause() приостанавливает выполнение процесса до тех пор, пока вызов не будет прерван обработчиком (или до тех пор, пока необрабатываемый сигнал не завершит процесс).

#include

int pause(void);

Всегда возвращает –1 с установкой errno в EINTR

При получении обрабатываемого сигнала функция pause() всегда прерывается и возвращает –1 с установкой errno в EINTR. (Более подробно об ошибке EINTR мы поговорим в разделе 21.5.) Пример использования функции pause() приведен в листинге 20.2.

В разделах 22.9–22.11 мы рассматриваем различные способы приостановки работы программы на время ожидания сигнала.

20.15. Резюме

Сигнал — это оповещение о том, что произошло некое событие. Сигнал может быть отпроцессу из ядра, из другого процесса или из самого себя. Существует набор стандартных сигналов, каждый из которых имеет уникальный номер и предназначение.

Доставка сигнала, как правило, асинхронна, а это означает, что невозможно предсказать, в какой точке сигнал прерывает выполнение процесса. В некоторых случаях (например, в случае с аппаратно-генерируемыми сигналами) сигналы доставляются синхронно, а это значит, что доставка случается предсказуемо и повторимо в определенной точке выполнения программы. По умолчанию сигнал может быть либо проигнорирован, либо приводит к завершению процесса (с дампом ядра или без), останавливает запущенный процесс или повторно запускает остановленный. Какое из действий будет выполнено, зависит от типа сигнала. Кроме того, в программе могут использоваться функции signal() или sigaction() для явного игнорирования сигнала или установки функции обработчика сигнала, определяемой программистом и активируемой при получении сигнала. Для обеспечения лучшей переносимости установку обработчика рекомендуется осуществлять с помощью функции sigaction().

Процесс (с необходимыми разрешениями) может отправить сигнал в другой процесс с помощью функции kill(). Отправка нулевого сигнала (0) — это один из способов определения существования процесса с заданным ID. У каждого процесса есть сигнальная маска, представляющая собой набор сигналов, доставка которых временно заблокирована. Они могут быть добавлены и удалены из сигнальной маски с помощью функции sigprocmask().

При получении заблокированного сигнала он остается в режиме ожидания до разблокирования. Стандартные сигналы не могут быть поставлены в очередь. Иными словами, сигнал может быть отмечен в качестве ожидающего (и, следовательно, доставлен позже) только однажды. Для получения набора ожидающих сигналов (структуры данных, используемой для представления нескольких различных сигналов и идентифицирующей сигналы, находящиеся в режиме ожидания), процесс может задействовать системный вызов sigpending().

При установке диспозиции сигнала системный вызов sigaction() предоставляет больше контроля и гибкости по сравнению с функцией signal(). В первую очередь мы можем указать набор дополнительных сигналов, блокируемых при активации обработчика. Вдобавок к этому мы можем использовать различные флаги для управления действиями, выполняемыми при активации обработчика сигнала. Например, существуют флаги, задействующие старую ненадежную семантику сигнала (сигнал, активировавший обработчик, не блокируется, а диспозиция сигнала сбрасывается к значению по умолчанию до вызова обработчика).

С помощью функции pause() процесс может прервать выполнение до получения сигнала.

Дополнительная информация

Перейти на страницу:

Похожие книги