Ответ
SIGCHLD — это сигнал, который ядро Linux отправляет родительскому процессу при изменении состояния его дочернего процесса (завершение, остановка SIGSTOP или возобновление SIGCONT).
Зачем это нужно в DevOps/администрировании?
Основная задача — предотвратить появление "зомби"-процессов (процессов, завершивших работу, но все еще занимающих запись в таблице процессов). Родительский процесс должен вызвать системный вызов wait() (или его варианты), чтобы получить статус завершения дочернего процесса и освободить ресурсы.
Практический пример в скрипте:
#!/bin/bash
# Устанавливаем обработчик для SIGCHLD
cleanup() {
echo "[$(date)] Дочерний процесс завершился. Выполняем wait."
wait -n # Ждем завершения любого дочернего процесса
}
trap cleanup SIGCHLD
# Запускаем несколько фоновых процессов
sleep 30 &
P1=$!
sleep 60 &
P2=$!
echo "Родительский процесс PID $$ запущен. Дочерние: $P1, $P2"
# Родительский процесс может продолжать свою работу
while true; do
echo "Родительский процесс работает..."
sleep 10
done
Ключевые моменты для DevOps:
- Демоны и супервизоры (systemd, supervisord) активно используют этот механизм для управления своими дочерними службами.
- Игнорирование SIGCHLD или отсутствие вызова
wait()может привести к утечке ресурсов (PID). - В контейнерах (Docker) процесс с PID 1 должен корректно обрабатывать SIGCHLD, чтобы перехватывать сигналы от своих дочерних процессов.
Ответ 18+ 🔞
А, слушай, вот тебе история про одного незаметного, но охуенно важного пацана в мире процессов — SIGCHLD. Представь: твой дочерний процесс на Linux, типа, закончил свои дела — отработал, сдох, остановился или, наоборот, очухался. Так вот ядро, такое заботливое, сразу шлёт родителю сигнал: «Эй, чувак, у тебя там ребёнок состояние поменял!». Это и есть SIGCHLD, ёпта.
А нахуя это вообще нужно нам, админам и девопсам?
Вот смотри, главная фишка — не допустить появления зомби. Нет, не тех, что за мозгом, а процессов, которые уже кончились, но в системной таблице торчат как бельмо на глазу, записи занимают. Родитель обязан сделать wait() (или его братьев), чтобы статус завершения забрать и ресурсы освободить. Иначе — мусор, утечка PID, в общем, пиздец, Карл.
Чисто практика, на баше:
#!/bin/bash
# Вешаем обработчик на SIGCHLD
cleanup() {
echo "[$(date)] Дочерний процесс завершился. Выполняем wait."
wait -n # Ждём любого дочернего
}
trap cleanup SIGCHLD
# Запускаем фоновые процессы, как будто они просто поспать легли
sleep 30 &
P1=$!
sleep 60 &
P2=$!
echo "Родительский процесс PID $$ запущен. Дочерние: $P1, $P2"
# Родитель может дальше свою работу делать, не заморачиваясь
while true; do
echo "Родительский процесс работает..."
sleep 10
done
Что тут важно для нашей братии, которая с серваками возится:
- Все эти ваши демоны и супервизоры (systemd, supervisord) — они на этом механизме просто помешаны. Без него управлять службами — это как пытаться собрать рассыпанную соль голыми руками, доверия ебать ноль.
- Если забить хуй на SIGCHLD и не вызывать
wait()— готовься к утечке PID. Это как оставлять после себя пустые бутылки на чужой даче — рано или поздно хозяин приедет и ебёт тебя в сраку. - Особенно трепетно к этому относятся в контейнерах (Docker). Там процесс с PID 1 — он как главный по тарелкам, обязан SIGCHLD обрабатывать правильно, чтобы сигналы от детей ловить. Иначе весь этот ваш красивый оркестр из микросервисов накроется медным тазом.