3.4.4. Асинхронное удаление дочерних процессов

3.4.4. Асинхронное удаление дочерних процессов

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

Один подход заключается в периодическом вызове функции wait3() или wait4(). Функция wait() в данной ситуации не подходит, так как в случае отсутствия завершившегося дочернего процесса она заблокирует основную программу. А вот упомянутые две функции принимают дополнительный флаг WNOHANG, переводящий их в неблокируемый режим, в котором функция либо удаляет дочерний процесс, если он есть, либо просто завершается. В первом случае возвращается идентификатор процесса, во втором — 0.

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

Таким образом, нужно организовать удаление дочерних процессов в обработчике сигнала SIGCHLD. Естественно, код состояния удаляемого процесса следует сохранять в глобальной переменной, если эта информация необходима основной программе. В листинге 3.7 показана программа, в которой реализована данная методика.

Листинг 3.7. (sigchld.c) Удаление дочерних процессов в обработчике сигнала SIGCHLD

#include <signal.h>

#include <string.h>

#include <sys/types.h>

#include <sys/wait.h>

sig_atomic_t child_exit_status;

void clean_up_child_process(int signal_number) {

 /* Удаление дочернего процесса. */

 int status;

 wait(&status);

 /* Сохраняем статус потомка в глобальной переменной. */

 child_exit_status = status;

}

int main() {

 /* Обрабатываем сигнал SIGCHLD, вызывая функцию

    clean_up_child_process(). */

 struct sigaction sigchld_action;

 memset(&sigchld_action, 0, sizeof(sigchld_action));

 sigchld_action.sa_handler = &clean_up_child_process;

 sigaction(SIGCHLD, &sigchld_action, NULL);

 /* Далее выполняются основные действия, включая порождение

    дочернего процесса. */

 /* ... */

 return 0;

}

Поделитесь на страничке

Следующая глава >

Похожие главы из других книг

Асинхронное удаленное взаимодействие

Из книги Язык программирования С# 2005 и платформа .NET 2.0. [3-е издание] автора Троелсен Эндрю

Асинхронное удаленное взаимодействие В завершение нашего обсуждения материала данной главы давайте выясним, как вызывать члены удаленного типа асинхронно. В главе 14 была рассмотрена тема асинхронного вызова методов с помощью типов делегата. Как и следует ожидать, при


Создание дочерних окон

Из книги Практика и проблематика моделирования бизнес-процессов автора Всяких Е И

Создание дочерних окон Заключительным шагом должно быть создание подходящей реализации обработчика событий Файл?Создать родительской формы. Теперь, когда дочерняя форма определена, соответствующая программная логика оказывается очень простой: нужно создать и


Обработка дочерних узлов

Из книги Разработка приложений в среде Linux. Второе издание автора Джонсон Майкл К.

Обработка дочерних узлов Элемент <xsl:apply-templates> дает указание процессору XSLT обрабатывать все совпадающие шаблоны для дочерних узлов контекстного узла. Элемент <xsl:apply-templates> дает возможность явно указать, когда следует закончить обработку дочерних узлов, а это имеет


Выбор дочерних элементов

Из книги Firebird РУКОВОДСТВО РАЗРАБОТЧИКА БАЗ ДАННЫХ автора Борри Хелен

Выбор дочерних элементов При доступе к дочернему узлу определенного узла для разделения имен элементов можно использовать операцию шага /. Пусть, например, требуется создать правило, которое должно применяться только к тем элементам <NAME>, которые являются дочерними


10.4. Примитивы процессов

Из книги Linux программирование в примерах автора Роббинс Арнольд

10.4. Примитивы процессов Несмотря на относительно длинную дискуссию, необходимую для описания процесса, создание и уничтожение процессов в Linux достаточно


10.4.1. Создание дочерних процессов

Из книги iOS. Приемы программирования автора Нахавандипур Вандад

10.4.1. Создание дочерних процессов В Linux предусмотрены два системных вызова, которые создают новые процессы: fork() и clone(). Как упоминалось ранее, clone() используется для создания потоков, и этот вызов будет кратко описан далее. А сейчас мы сосредоточимся на fork() — наиболее


10.4.2. Наблюдение за уничтожением дочерних процессов

Из книги UNIX: разработка сетевых приложений автора Стивенс Уильям Ричард

10.4.2. Наблюдение за уничтожением дочерних процессов Сбор состояний возврата дочернего процесса называется ожиданием процесса. Это можно делать четырьмя способами, хотя только один из вызовов предоставляется ядром. Остальные три метода реализованы в стандартной


15.1.2. Остановка процессов

Из книги автора

15.1.2. Остановка процессов Четыре сигнала перемещают работающий процесс в состояние останова. SIGSTOP никогда не генерируется ядром. Он предназначен для остановки произвольных процессов. Его невозможно захватить или проигнорировать; он всегда останавливает целевой процесс.


Асинхронное прослушивание

Из книги автора

Асинхронное прослушивание Прежде чем вы сможете использовать функцию сигнализации API isc_que_evento, вам нужно выполнить функцию обратного вызова на клиенте, которую вызывал бы сервер при посылке события. Названием для такого типа функции является асинхронный перехват, или


14.4.6. Удаление вершины дерева и удаление дерева: tdelete() и tdestroy()

Из книги автора

14.4.6. Удаление вершины дерева и удаление дерева: tdelete() и tdestroy() Наконец, вы можете удалить элементы из дерева и, на системах GLIBC, удалить само дерево целиком:void *tdelete(const void *key, void **rootp,int (*compare)(const void*, const void*));/* Расширение GLIBC, в POSIX нет: */void tdestroy(void *root, void (*free_node)(void *nodep));Аргументы


7.6. Асинхронное решение с помощью GCD задач, не связанных с пользовательским интерфейсом

Из книги автора

7.6. Асинхронное решение с помощью GCD задач, не связанных с пользовательским интерфейсом Постановка задачи Необходимо иметь возможность решать задачи, не связанные с пользовательским интерфейсом, с помощью


Эффект наличия слишком большого количества дочерних процессов

Из книги автора

Эффект наличия слишком большого количества дочерних процессов В табл. 30.1 (строка 2) указано время (1,8 с), затрачиваемое центральным процессором в случае наличия 15 дочерних процессов, обслуживающих не более 10 клиентов. Мы можем оценить эффект «общей побудки», увеличивая


Эффект наличия слишком большого количества дочерних процессов

Из книги автора

Эффект наличия слишком большого количества дочерних процессов Мы можем проверить, возникает ли в данной версии сервера эффект «общей побудки», рассмотренный в предыдущем разделе. Как и раньше, время работы ухудшается пропорционально числу избыточных дочерних