Читаем UNIX: разработка сетевых приложений полностью

7 POSIX позволяет нам задавать набор сигналов, которые будут блокированы при вызове обработчика сигналов. Любой блокируемый сигнал не может быть доставлен процессу. Мы устанавливаем элемент sa_mask равным пустому набору. Это означает, что во время работы обработчика дополнительные сигналы не блокируются. POSIX гарантирует, что перехватываемый сигнал всегда блокирован, пока выполняется его обработчик.

Установка флага SA_RESTART

8-17 Флаг SA_RESTART не является обязательным, и если он установлен, то системный вызов, прерываемый этим сигналом, будет автоматически снова выполнен ядром. (В продолжении нашего примера мы более подробно поговорим о прерванных системных вызовах.) Если перехватываемый сигнал не является сигналом SIGALRM, мы задаем флаг SA_RESTART, если таковой определен. (Причина, по которой сигнал SIGALRM обрабатывается отдельно, состоит в том, что обычно цель его генерации - ввести ограничение по времени в операцию ввода-вывода, как показано в листинге 14.2. В этом случае мы хотим, чтобы блокированный системный вызов был прерван сигналом.) Более ранние системы, особенно SunOS 4.x, автоматически перезапускают прерванный системный вызов по умолчанию и затем определяют флаг SA_INTERRUPT. Если этот флаг задан, мы устанавливаем его при перехвате сигнала SIGALRM.

Вызов функции sigaction

18-20 Мы вызываем функцию sigaction, а затем возвращаем старое действие сигнала как результат функции signal.

В книге мы везде используем функцию signal из листинга 5.5.

<p>Семантика сигналов POSIX</p>

Сведем воедино следующие моменты, относящиеся к обработке сигналов в системе, совместимой с POSIX.

■ Однажды установленный обработчик сигналов остается установленным (в более ранних системах обработчик сигналов удалялся каждый раз по выполнении).

■ На время выполнения функции — обработчика сигнала доставляемый сигнал блокируется. Более того, любые дополнительные сигналы, заданные в наборе сигналов sa_mask, переданном функции sigaction при установке обработчика, также блокируются. В листинге 5.5 мы устанавливаем sa_mask равным пустому набору, что означает, что никакие сигналы, кроме перехватываемого, не блокируются.

■ Если сигнал генерируется один или несколько раз, пока он блокирован, то обычно после разблокирования он доставляется только один раз, то есть по умолчанию сигналы Unix не устанавливаются в очередь. Пример мы рассмотрим в следующем разделе. Стандарт POSIX реального времени 1003.1b определяет набор надежных сигналов, которые помещаются в очередь, но в этой книге мы их не используем.

■ Существует возможность выборочного блокирования и разблокирования набора сигналов с помощью функции sigprocmask. Это позволяет нам защитить критическую область кода, не допуская перехватывания определенных сигналов во время ее выполнения.

<p>5.9. Обработка сигнала SIGCHLD</p>

Назначение состояния зомби — сохранить информацию о дочернем процессе, чтобы родительский процесс мог ее впоследствии получить. Эта информация включает идентификатор дочернего процесса, статус завершения и данные об использовании ресурсов (время процессора, память и т.д.). Если у завершающегося процесса есть дочерний процесс в зомбированном состоянии, идентификатору родительского процесса всех зомбированных дочерних процессов присваивается значение 1 (процесс init), что позволяет унаследовать дочерние процессы и сбросить их (то есть процесс init будет ждать (wait) их завершения, благодаря чему будут удалены зомби). Некоторые системы Unix в столбце COMMAND выводят для зомбированных процессов значение .

<p>Обработка зомбированных процессов</p>

Очевидно, что нам не хотелось бы оставлять процессы в виде зомби. Они занимают место в ядре, и в конце концов у нас может не остаться идентификаторов для нормальных процессов. Когда мы выполняем функцию fork для дочерних процессов, необходимо с помощью функции wait дождаться их завершения, чтобы они не превратились в зомби. Для этого мы устанавливаем обработчик сигналов для перехватывания сигнала SIGCHLD и внутри обработчика вызываем функцию wait. (Функции wait и waitpid мы опишем в разделе 5.10.) Обработчик сигналов мы устанавливаем с помощью вызова функции

Signal(SIGCHLD, sig_chld);

в листинге 5.1, после вызова функции listen. (Необходимо сделать это до вызова функции fork для первого дочернего процесса, причем только один раз.) Затем мы определяем обработчик сигнала — функцию sig_chld, представленную в листинге 5.6.

Листинг 5.6. Версия обработчика сигнала SIGCHLD, вызывающая функцию wait (усовершенствованная версия находится в листинге 5.8)

//tcpcliserv/sigchldwait.с

 1 #include "unp.h"

 2 void

 3 sig_chld(int signo)

 4 {

 5  pid_t pid;

 6  int stat;

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

Все книги серии Мастер-класс

Секреты резьбы по дереву
Секреты резьбы по дереву

Изделия из древесины и материалов, имитирующих ее текстуру, привычным образом окружают нас в повседневной жизни, поэтому мы относимся к ней как к чему-то обыденному. Но как только ее коснется умелая рука мастера резьбы по дереву, рождается произведение искусства и раскрываются такие качества древесины, как богатая фактура, разнообразие цветов, особая теплота. Эта книга поможет читателю открыть для себя удивительный мир творчества и познать секреты резьбы по дереву. Автор надеется, что начинающие резчики найдут в ней интересный и полезный материал, который позволит им стать мастерами. В приложении представлены рисунки орнаментов и различных узоров, которые на первых порах можно копировать, а по мере приобретения навыка на их основе разрабатывать свои образцы.

Галина Алексеевна Серикова

Сделай сам / Хобби и ремесла / Руководства / Дом и досуг / Словари и Энциклопедии

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