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;
}
Более 800 000 книг и аудиокниг! 📚
Получи 2 месяца Литрес Подписки в подарок и наслаждайся неограниченным чтением
ПОЛУЧИТЬ ПОДАРОКЧитайте также
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));Аргументы
Обработка дочерних узлов
Обработка дочерних узлов Элемент <xsl:apply-templates> дает указание процессору XSLT обрабатывать все совпадающие шаблоны для дочерних узлов контекстного узла. Элемент <xsl:apply-templates> дает возможность явно указать, когда следует закончить обработку дочерних узлов, а это имеет
Выбор дочерних элементов
Выбор дочерних элементов При доступе к дочернему узлу определенного узла для разделения имен элементов можно использовать операцию шага /. Пусть, например, требуется создать правило, которое должно применяться только к тем элементам <NAME>, которые являются дочерними
10.4. Примитивы процессов
10.4. Примитивы процессов Несмотря на относительно длинную дискуссию, необходимую для описания процесса, создание и уничтожение процессов в Linux достаточно
10.4.1. Создание дочерних процессов
10.4.1. Создание дочерних процессов В Linux предусмотрены два системных вызова, которые создают новые процессы: fork() и clone(). Как упоминалось ранее, clone() используется для создания потоков, и этот вызов будет кратко описан далее. А сейчас мы сосредоточимся на fork() — наиболее
10.4.2. Наблюдение за уничтожением дочерних процессов
10.4.2. Наблюдение за уничтожением дочерних процессов Сбор состояний возврата дочернего процесса называется ожиданием процесса. Это можно делать четырьмя способами, хотя только один из вызовов предоставляется ядром. Остальные три метода реализованы в стандартной
15.1.2. Остановка процессов
15.1.2. Остановка процессов Четыре сигнала перемещают работающий процесс в состояние останова. SIGSTOP никогда не генерируется ядром. Он предназначен для остановки произвольных процессов. Его невозможно захватить или проигнорировать; он всегда останавливает целевой процесс.
Эффект наличия слишком большого количества дочерних процессов
Эффект наличия слишком большого количества дочерних процессов В табл. 30.1 (строка 2) указано время (1,8 с), затрачиваемое центральным процессором в случае наличия 15 дочерних процессов, обслуживающих не более 10 клиентов. Мы можем оценить эффект «общей побудки», увеличивая
Эффект наличия слишком большого количества дочерних процессов
Эффект наличия слишком большого количества дочерних процессов Мы можем проверить, возникает ли в данной версии сервера эффект «общей побудки», рассмотренный в предыдущем разделе. Как и раньше, время работы ухудшается пропорционально числу избыточных дочерних
Асинхронное удаленное взаимодействие
Асинхронное удаленное взаимодействие В завершение нашего обсуждения материала данной главы давайте выясним, как вызывать члены удаленного типа асинхронно. В главе 14 была рассмотрена тема асинхронного вызова методов с помощью типов делегата. Как и следует ожидать, при
Создание дочерних окон
Создание дочерних окон Заключительным шагом должно быть создание подходящей реализации обработчика событий Файл?Создать родительской формы. Теперь, когда дочерняя форма определена, соответствующая программная логика оказывается очень простой: нужно создать и
7.6. Асинхронное решение с помощью GCD задач, не связанных с пользовательским интерфейсом
7.6. Асинхронное решение с помощью GCD задач, не связанных с пользовательским интерфейсом Постановка задачи Необходимо иметь возможность решать задачи, не связанные с пользовательским интерфейсом, с помощью
7.12. Асинхронное выполнение задач с помощью операций
7.12. Асинхронное выполнение задач с помощью операций Постановка задачи Требуется параллельно выполнять
Асинхронное прослушивание
Асинхронное прослушивание Прежде чем вы сможете использовать функцию сигнализации API isc_que_evento, вам нужно выполнить функцию обратного вызова на клиенте, которую вызывал бы сервер при посылке события. Названием для такого типа функции является асинхронный перехват, или