Что произойдет с дочерними процессами процесса которому был отправлен сигнал sigkill

SIGTERM против SIGKILL: в чем разница?

Главное меню » Linux » SIGTERM против SIGKILL: в чем разница?

Что произойдет с дочерними процессами процесса которому был отправлен сигнал sigkill. Смотреть фото Что произойдет с дочерними процессами процесса которому был отправлен сигнал sigkill. Смотреть картинку Что произойдет с дочерними процессами процесса которому был отправлен сигнал sigkill. Картинка про Что произойдет с дочерними процессами процесса которому был отправлен сигнал sigkill. Фото Что произойдет с дочерними процессами процесса которому был отправлен сигнал sigkill

Поскольку управление процессами является отдельной темой, мы не будем подробно останавливаться на управлении пользовательскими процессами и обработке сигналов в этом посте.

Мы собираемся сосредоточиться на использовании сигналов SIGTERM и SIGKILL для завершения процесса. А также расскажем о том, почему вы должны избегать использования SIGKILL.

Что такое SIGTERM?

В UNIX-подобных системах сигнал SIGTERM используется для завершения программы. Вы можете догадаться об этом по его названию, которое состоит из SIGnal и TERMinate.

SIGTERM также может называться «мягким уничтожением», поскольку процесс, который получает сигнал SIGTERM, может игнорировать его.

Как отправить SIGTERM процессу в Linux?

Команда kill в Linux используется для отправки всех таких сигналов процессам.

Вам нужно знать pid процесса, чтобы использовать эту команду следующим образом:

Вы можете использовать команду ps в Linux, чтобы получить идентификатор процесса.

Что такое SIGKILL?

SIGKILL используется для немедленного прекращения процесса. Этот сигнал нельзя игнорировать или заблокировать. Процесс будет завершен вместе с его потоками (если есть).

Как отправить SIGKILL процессу в Linux?

SIGTERM vs SIGKILL: Почему вы должны использовать SIGTERM вместо SIGKILL?

Хотя оба эти сигнала используются для уничтожения процесса, между ними есть некоторые различия:

С помощью SIGTERM процесс получает время для отправки информации своим родительским и дочерним процессам. Это дочерние процессы обрабатываются init.

Использование SIGKILL может привести к созданию процесса зомби, потому что уничтоженный процесс не получает возможности сообщить своему родительскому процессу, что он получил сигнал уничтожения.

Если у вас есть какие-либо вопросы или предложения, пожалуйста, не стесняйтесь оставлять комментарии.

Если вы нашли ошибку, пожалуйста, выделите фрагмент текста и нажмите Ctrl+Enter.

Источник

Практика работы с сигналами

Функция обработчик сигналов

Данная функция вызывается, когда процесс (или нить) получает неблокируемый сигнал. Дефолтный обработчик завершает наш процесс (нить). Но мы можем сами определить обработчики для интересующих нас сигналов. Следует очень осторожно относится к написанию обработчика сигналов, это не просто функция, выполняющаяся по коллбеку, происходит прерывание текущего потока выполнения без какой либо подготовительной работы, таким образом глобальные объекты могут находится в неконсистентном состоянии. Автор не берется приводить свод правил, так как сам их не знает, и призывает последовать совету Kobolog (надеюсь он не против, что я ссылаюсь на него) и изучить хотя бы вот этот материал FAQ.

Установить новый обработчик сигнала можно двумя функциями

Здесь мы установили наш обработчик для сигналов SIGUSR1 и SUGUSR2, а также указали, что необходимо блокировать эти же сигналы пока выполняется обработчик.
С обработчиком сигналов есть один не очень удобный момент, он устанавливается на весь процесс и все порожденные нити сразу. Мы не имеет возможность для каждой нити установить свой обработчик сигналов.
Но при этом следует понимать что когда сигнал адресуется процессу, обработчик вызывается именно для главной нити (представляющей процесс). Если же сигнал адресуется для нити, то обработчик вызывается из контекста этой нити. См пример 1.

Блокирование сигналов

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

Мы можем к уже существующей маске сигналов добавить новые сигналы (SIG_BLOCK), можем из этой маски убрать часть сигналов (SIG_UNBLOCK), а так же установить полностью нашу маску сигналов (SIG_SETMASK).
Для работы с маской сигналов внутри нити используется функция

которая позволяет сделать все тоже, но уже для каждой нити в отдельности.
Невозможно заблокировать сигналы SIGKILL или SIGSTOP при помощи этих функций. Попытки это сделать будут игнорироваться.

sigwait

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

Посыл сигнала

Для того, чтобы послать сигнал процессу можно использовать две функции

С первой все понятно. Вторая нужна для того, чтобы послать сигнал самому себе, и по сути равносильна kill(getpid(), signal). Функция getpid() возвращает PID текущего процесса.
Для того, чтобы послать сигнал отдельной нити, используется функция

Пример использования сигналов

Все, что я описал выше, не дает ответа на вопрос «Зачем мне использовать сигналы». Теперь я хотел бы привести реальный пример использования сигналов и где без них попросту не обойтись.
Представьте, что вы хотите читать или писать какие-то данные в какое то устройство, но это может привести к блокированию. Ну например, чтение в случае работы с сокетами. Или может быть запись в пайп. Вы можете вынести это в отдельный поток, чтобы не блокировать основную работу. Но что делать когда вам нужно завершить приложение? Как корректно прервать блокирующую операцию IO? Можно было бы задавать таймаут, но это не очень хорошее решение. Для этого есть более удобные средства: функции pselect и ppoll. Разница между ними исключительно в юзабельности, поведение у них одинаковое. В первую очередь эти функции нужны для мультиплексирования работы с IO (select/poll). Префикс ‘p’ в начале функции указывает на то, что данная функция может быть корректно прервана сигналом.

Итак, сформулируем требование:
Необходимо разработать приложение, открывающее сокет (для простоты UDP) и выполняющее в потоке операцию чтения. Данное приложение должно корректно без задержек завершаться по требованию пользователя.
Функция треда выглядит вот так

Устанавливаем наш обработчик для SIGINT, и когда нужно завершить дочерний поток шлем ему этот сигнал.
Полный листинг см. пример 3.

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

PS. Исходные коды разместил на сервисе PasteBin (ссылку не даю, а то еще за рекламу посчитают).
PPS. Прошу простить за обилие ошибок. Язык, слабая моя сторона. Спасибо, всем кто помог их исправить.

Данная статья не претендует на полное (и глубокое) описание работы с сигналами и нацелена в первую очередь на тех, кто до этого момента не сталкивались с понятием «сигнал». Для более глубоко понимания работы сигналов автор призывает обратиться в более компетентные источники и ознакомиться с конструктивной критикой в комментариях.

Источник

Русские Блоги

Сигналы для взаимодействия процессов Linux-C

Сигналы для взаимодействия процессов Linux-C

1. Краткое описание

Сигналы ноты используются для связи между процессами. Асинхронные сигналы включают в себя: сигналы не в реальном времени и сигналы в реальном времени.

Сигналы в реальном времени должны отвечать, информационные номера не в реальном времени могут не отвечать (могут быть проигнорированы или потеряны)

Сигнал обычно имеет следующие настройки:
1, захват 1 (получение сигнала, выполнение указанного действия, а не по умолчанию)
2, 2, игнорировать (принять сигнал, ничего не делать)
3. Блокировка (принять сигнал, сначала выполнить текущую операцию, а затем ответить на сигнал)
4 в соответствии с действием по умолчанию

Примечание: SIGKILL, SIGSTOP не могут быть захвачены

Пожалуйста, обратитесь к руководству man: man 7 signal для подробного описания сигналов.

Во-вторых, signal () и kill ()

функция сигнала ()

typedef void (* sighandler_t) (int); // указатель на функцию обработки сигнала

sighandler_t signal(int signum, sighandler_t handler);

signum: сигнал для захвата

обработчик: метод обработки

1. SIG_IGN: игнорировать этот сигнал
2. SIG_DFL: выполнить этот сигнал в соответствии с действием по умолчанию
3. Если это функция, она должна захватить этот сигнал и выполнить эту функцию при получении этого сигнала.

Успех: возвращает предыдущее значение обработчика сигнала

Ошибка: верните SIG_ERR и установите errno

функцияПростая функция обработки сигнала (функция захвата сигнала)
Заголовочный файл#include
прототип
замечаниеПожалуйста, обратитесь к руководству man для деталей: сигнал человека 2 (также в седьмой книге). Может использоваться вместе с функцией kill (), которая отправляет указанный сигнал процессу.

Тестовый код 1: захват сигнала прерывания (SIGINT), после получения сигнала прерывания выведите предложение «получить сигнал% d \ n». Сигнал терминала отправляется, когда терминал нажимает Ctrl + C. Перед захватом сигнал терминала завершает программу по умолчанию.

Захват сигнала терминала:

Что произойдет с дочерними процессами процесса которому был отправлен сигнал sigkill. Смотреть фото Что произойдет с дочерними процессами процесса которому был отправлен сигнал sigkill. Смотреть картинку Что произойдет с дочерними процессами процесса которому был отправлен сигнал sigkill. Картинка про Что произойдет с дочерними процессами процесса которому был отправлен сигнал sigkill. Фото Что произойдет с дочерними процессами процесса которому был отправлен сигнал sigkill

Что произойдет с дочерними процессами процесса которому был отправлен сигнал sigkill. Смотреть фото Что произойдет с дочерними процессами процесса которому был отправлен сигнал sigkill. Смотреть картинку Что произойдет с дочерними процессами процесса которому был отправлен сигнал sigkill. Картинка про Что произойдет с дочерними процессами процесса которому был отправлен сигнал sigkill. Фото Что произойдет с дочерними процессами процесса которому был отправлен сигнал sigkill

функция kill ()

pid: идентификатор процесса (идентификатор процесса)

sig: сигнал для отправки

Успех: возвращает 0

функцияОтправить сигнал процессу
Заголовочный файл#include
#include
прототипint kill(pid_t pid, int sig);
параметры
замечаниеПожалуйста, проверьте руководство man для деталей: man 2 kill

Тестовый код 2: Используйте функцию kill () для отправки сигнала SIGUSR1 в сигнальную программу. После того, как программа перехватит его, напечатайте предложение «получить сигнал% d \ n» и затем выйдите.

Что произойдет с дочерними процессами процесса которому был отправлен сигнал sigkill. Смотреть фото Что произойдет с дочерними процессами процесса которому был отправлен сигнал sigkill. Смотреть картинку Что произойдет с дочерними процессами процесса которому был отправлен сигнал sigkill. Картинка про Что произойдет с дочерними процессами процесса которому был отправлен сигнал sigkill. Фото Что произойдет с дочерними процессами процесса которому был отправлен сигнал sigkill

Три, sigprocmask () блокировка сигнала

Блокировка сигнала: во время процесса блокировки сигнал не будет потерян, он будет приостановлен, и он ответит, когда снятие блокировки.

функция sigprocmask ()

how: работа с сигналом (применяется ко всем функциям в наборе сигналов)

SIG_BLOCK: добавить сигнал в сигнал, установленный для блокировки (добавить настройку к исходной настройке)
SIG_UNBLOCK: разблокировать сигналы в наборе сигналов.
SIG_SETMASK: напрямую блокировать сигналы в наборе сигналов, исходные настройки прямо перезаписываются.

набор: набор сигналов для установки
Int sigemptyset (sigset_t * set); // Пустой набор сигналов
Int sigfillset (sigset_t * set); // Зарегистрировать все сигналы в наборе
Int sigaddset (sigset_t * set, int signum); // Добавить сигнал signum в набор
Int sigdelset (sigset_t * set, int signum); // Удалить сигнал signum в коллекцию
Int sigismember (const sigset_t * set, int signum); // Проверить, есть ли сигнал signum в наборе сигналов

oldset: используется для сохранения старых настроек набора сигналов
Если это конкретный указатель, сохраните исходные настройки здесь
Если он равен NULL, он не будет сохранен.

Успех: возвращает 0

функцияЗаблокируйте сигнал и задержите ответ. (Проверьте и измените заблокированный сигнал)
Заголовочный файл#include
прототипint sigprocmask(int how, const sigset_t *set, sigset_t *oldset);
параметры
замечаниеВ состоянии блокировки сигналы не в реальном времени могут быть потеряны

Что произойдет с дочерними процессами процесса которому был отправлен сигнал sigkill. Смотреть фото Что произойдет с дочерними процессами процесса которому был отправлен сигнал sigkill. Смотреть картинку Что произойдет с дочерними процессами процесса которому был отправлен сигнал sigkill. Картинка про Что произойдет с дочерними процессами процесса которому был отправлен сигнал sigkill. Фото Что произойдет с дочерними процессами процесса которому был отправлен сигнал sigkill

4. Отправка и обработка сигналов с данными:sigaction() И сигку ()

функция sigaction ()

signum: захваченный сигнал

act: Структура действия сигнала, используемая для регистрации действия для обработки этого сигнала.

struct sigaction
<
void * (* sa_handler) (int); // функция обработки сигнала без параметров, функция обработки сигнала без параметров выполняется по умолчанию
void * (* sa_sigaction) (int, siginfo_t *, void *); // Функция обработки сигналов с параметрами, если вы хотите включить эту функцию обработки сигналов,
”” ”” ”” ”” ”” ”” необходимо установить для sa_flags значение SA_SIGINFO
sigset_t sa_mask; // настройка блокировки сигнала
”” ”” ”” ”” ”” ”” / 1 // 1, блокируя указанный сигнал во время выполнения функции обработки сигнала,

// указанный сигнал будет приостановлен и будет выполнен после окончания функции
”” ”” ”” ”” ”” ”” / 2/2, тип сбора сигналов sigset_t, см. использование sigset в sigprocmask.

int _ sa_flags; // идентификация операции сигнала, например, использовать ли функцию обработки сигнала с параметрами или без параметров
void * (* sa_restorer) (void); // Заброшенные настройки
>;

oldact: используется для сохранения исходных настроек, если NULL не сохраняется.

Успех: возвращает 0

функцияПроверка и изменение действий сигналов (захват сигналов, указание действий обработки)
Заголовочный файл#include
прототипint sigaction(int signum, const struct sigaction *act,struct sigaction *oldact);
параметры
замечаниеsiginfo_t
<
int si_signo; /* Signal number */
int si_errno; /* An errno value */
int si_code; /* Signal code */
int si_trapno; /* Trap number that caused
hardware-generated signal
(unused on most architectures) */
pid_t si_pid; /* Sending process ID */
uid_t si_uid; /* Real user ID of sending process */
int si_status; /* Exit value or signal */
clock_t si_utime; /* User time consumed */
clock_t si_stime; /* System time consumed */
sigval_t si_value; /* Signal value */
int si_int; /* POSIX.1b signal */
void *si_ptr; /* POSIX.1b signal */
int si_overrun; /* Timer overrun count;
POSIX.1b timers */
int si_timerid; /* Timer ID; POSIX.1b timers */
void *si_addr; /* Memory location which caused fault */
long si_band; /* Band event (was int in
glibc 2.3.2 and earlier) */
int si_fd; /* File descriptor */
short si_addr_lsb; /* Least significant bit of address
(since Linux 2.6.32) */
void *si_lower; /* Lower bound when address violation
occurred (since Linux 3.19) */
void *si_upper; /* Upper bound when address violation
occurred (since Linux 3.19) */
int si_pkey; /* Protection key on PTE that caused
fault (since Linux 4.6) */
void *si_call_addr; /* Address of system call instruction
(since Linux 3.5) */
int si_syscall; /* Number of attempted system call
(since Linux 3.5) */
unsigned int si_arch; /* Architecture of attempted system call
(since Linux 3.5) */
>;

функция сигки

pid: идентификатор процесса

sig: сигнал для отправки

значение: дополнительные данные

union sigval
<
  int sival_int; // прикреплены только одни данные int
¡void * sival_ptr; // Добавить дополнительные данные (добавить адрес)
>;

Примечание: // Это сообщество, в зависимости от того, что наступит раньше

Успех: возвращает 0

функцияОтправить сигналы и данные в указанный процесс
Заголовочный файл#include
прототипint sigqueue(pid_t pid, int sig, const union sigval value);
параметры
замечаниеИспользуйте с подписью

Пример: программа sigqueue отправляет сигнал SIGUSR1 в программу sigaction вместе с данными 123 типа int. После того, как sigaction перехватывает сигнал, она печатает PID и дополнительные данные отправителя сигнала и затем завершает работу.

Тестовый код:

файл sigaction.c

файл sigqueue.c

Результат операции:

Что произойдет с дочерними процессами процесса которому был отправлен сигнал sigkill. Смотреть фото Что произойдет с дочерними процессами процесса которому был отправлен сигнал sigkill. Смотреть картинку Что произойдет с дочерними процессами процесса которому был отправлен сигнал sigkill. Картинка про Что произойдет с дочерними процессами процесса которому был отправлен сигнал sigkill. Фото Что произойдет с дочерними процессами процесса которому был отправлен сигнал sigkill

V. Дополнение

1. Просмотр информации, связанной с процессом

Ps: просмотр статуса процесса (мгновенный статус процесса, статический)
top: «Просмотр в реальном времени», нажмите q для выхода (динамическое отображение в реальном времени)
древовидное представление дерева (вы можете видеть дочерний процесс)

Что произойдет с дочерними процессами процесса которому был отправлен сигнал sigkill. Смотреть фото Что произойдет с дочерними процессами процесса которому был отправлен сигнал sigkill. Смотреть картинку Что произойдет с дочерними процессами процесса которому был отправлен сигнал sigkill. Картинка про Что произойдет с дочерними процессами процесса которому был отправлен сигнал sigkill. Фото Что произойдет с дочерними процессами процесса которому был отправлен сигнал sigkill

Что произойдет с дочерними процессами процесса которому был отправлен сигнал sigkill. Смотреть фото Что произойдет с дочерними процессами процесса которому был отправлен сигнал sigkill. Смотреть картинку Что произойдет с дочерними процессами процесса которому был отправлен сигнал sigkill. Картинка про Что произойдет с дочерними процессами процесса которому был отправлен сигнал sigkill. Фото Что произойдет с дочерними процессами процесса которому был отправлен сигнал sigkill

Что произойдет с дочерними процессами процесса которому был отправлен сигнал sigkill. Смотреть фото Что произойдет с дочерними процессами процесса которому был отправлен сигнал sigkill. Смотреть картинку Что произойдет с дочерними процессами процесса которому был отправлен сигнал sigkill. Картинка про Что произойдет с дочерними процессами процесса которому был отправлен сигнал sigkill. Фото Что произойдет с дочерними процессами процесса которому был отправлен сигнал sigkill

2. Отправить сигнал процессу

Что произойдет с дочерними процессами процесса которому был отправлен сигнал sigkill. Смотреть фото Что произойдет с дочерними процессами процесса которому был отправлен сигнал sigkill. Смотреть картинку Что произойдет с дочерними процессами процесса которому был отправлен сигнал sigkill. Картинка про Что произойдет с дочерними процессами процесса которому был отправлен сигнал sigkill. Фото Что произойдет с дочерними процессами процесса которому был отправлен сигнал sigkill

Среди них SIGKILL и SIGSTOP могут выполняться только в соответствии с действием системы по умолчанию и не могут быть захвачены, заблокированы и проигнорированы

Следующие 31 являются сигналами в реальном времени:
1, сигнал не будет потерян
2. Приоритет выше, чем сигналы не в реальном времени

3. Наследование сигналов
1, параметр инициализации сигнала будет унаследован дочерним процессом
2, настройка блокировки сигнала будет унаследована дочерним процессом
3, приостановленный сигнал не будет унаследован дочерним процессом

4. На что следует обратить внимание в функции обработки сигналов:
1, глобальные переменные не должны обрабатываться в функциях обработки сигналов (если вы хотите работать, не забудьте заблокировать)
2, вы должны обратить внимание на безопасность некоторых вызовов функций, вы можете проверить сигнал man 7

5. Проверьте приоритет ответа всех сигналов

Сигнал реального времени 34-64: приоритетный ответ с большими числами;

Источник

Вызов kill для дочернего процесса с помощью SIGTERM завершает родительский процесс, но вызов с помощью SIGKILL сохраняет родительский процесс

несмотря на то, что SIGKILL работает, я хочу использовать SIGTERM, потому что это похоже на лучшую идею в целом из того, что я читал об этом, давая процессу сигнал прекратить шанс очистить себя.

приведенный ниже код является раздели пример того, что я придумал

может кто-нибудь объяснить, почему это происходит?

как я отмечаю, я не в восторге от моего

1 ответов

у вас слишком много ошибок в коде (не сняв маску сигналов на struct sigaction ) для любого, чтобы объяснить эффекты, которые вы видите.

вместо этого, рассмотрим следующий пример рабочего кода, скажем example.c :

скомпилируйте его, используя, например,

и запустите, используя, например,

вы можете выйти из sqlite3 С помощью или клавишей Ctrl + D в начале строки.

можно использовать ps f чтобы посмотреть на дерево ваших терминальных процессов, и таким образом узнать PIDs родительских и дочерних процессов и отправить сигналы либо одному, чтобы наблюдать, что происходит.

отметим, что SIGSTOP сигнал нельзя уловить, преградить, или проигнорировать, было бы нетривиально отразить сигналы управлением работы (как в когда вы используете Ctrl + Z ). Для надлежащего управления заданием родительскому процессу потребуется настроить новый сеанс и группу процессов, а также временно отсоединиться от терминала. Это тоже вполне возможно, но немного выходит за рамки здесь, поскольку это включает в себя довольно подробное поведение сеансов, групп процессов и терминалов для правильного управления.

давайте разберем приведенный выше пример программы.

на internal_child_pid переменной, и set_child_pid() и get_child_pid() функции, используются для управления дочерним процессом атомарно. The __atomic_store_n() и __atomic_load_n() предоставляются компилятором встроенные модули; для GCC, посмотреть здесь для сведения. Им избежать проблемы сигнал возникает, когда ребенок пид назначается только частично. На некоторых распространенных архитектурах это не может произойти, но это предназначено в качестве осторожного примера, поэтому атомарные обращения используются для обеспечения только полностью (old или new) значение всегда видно. Мы могли бы полностью избежать их использования, если бы временно заблокировали соответствующие сигналы во время перехода. Опять же, я решил, что атомарный доступ проще и может быть интересно посмотреть на практике.

на forward_handler() функция получает ребенок процесс PID атомарно, затем проверяет, что он ненулевой (что мы знаем, что у нас есть дочерний процесс), и что мы не передаем сигнал, отправленный дочерним процессом (просто чтобы убедиться, что мы не вызываем шторм сигнала, два бомбардируют друг друга сигналами). Различные поля в siginfo_t структура, перечислены в man 2 sigaction man page.

важно использовать sigemptyset(&act.sa_mask) очистить маску сигнала. Простой установки структуры на ноль недостаточно, даже если она работает (вероятно) на практике на многих машинах. (Не знаю, я даже не проверял. Я предпочитаю крепкий и надежный над ленивым и хрупким в любой день!)

используемые флаги включают SA_SIGINFO потому что обработчик использует форму трех аргументов (и использует the о siginfo_t ). SA_RESTART флаг существует только потому, что OP хотел его использовать; это просто означает, что, если возможно, библиотека C и ядро пытаются избежать возврата errno == EINTR ошибка, если сигнал поставляется с использованием потока, в настоящее время блокирующего в syscall (например, wait() ). Вы можете удалить SA_RESTART флаг, и добавить отладки fprintf(stderr, «Hey!\n»); в подходящем месте в цикле в Родительском процессе, чтобы увидеть, что произойдет потом.

на execlp() функция принимает два аргумента: имя двоичного файла (будут использоваться каталоги, указанные в переменной среды PATH для поиска такого двоичного файла), а также массив указателей на аргументы этого двоичного файла. Первым аргументом будет argv[0] в новом двоичном файле, т. е. само имя команды.

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

вместо этого мы могли бы просто блокировать эти сигналы, используя, например, sigprocmask() в Родительском процессе перед разветвлением. Блокировка сигнала означает, что он «ждет»; он не будет доставлен, пока сигнал не будет разблокирован. В дочерний процесс, сигналы могут оставаться заблокированными, так как диспозиции сигналов сбрасываются по умолчанию над exec() в любом случае. В Родительском процессе мы могли бы затем-или перед раздвоением, это не имеет значения-установить обработчики сигналов и, наконец, разблокировать сигналы. Таким образом, нам не нужен атомарный материал и даже не нужно проверять, равен ли дочерний pid нулю, поскольку дочерний pid будет установлен на его фактическое значение задолго до того, как какой-либо сигнал может быть доставлен!

на while цикл в основном просто петля вокруг waitpid() вызов, пока точный дочерний процесс, который мы начали выходить, или что-то смешное происходит (дочерний процесс исчезает каким-то образом). Этот цикл содержит довольно тщательную проверку ошибок, а также правильную EINTR вручать если обработчики сигнала должны были быть установлены без SA_RESTART флаги.

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

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *