Я пытаюсь построить контейнер процесса. Контейнер будет запускать другие программы. Например, bash-скрипт, запускающий фоновые задачи с использованием '&'.
Важная особенность, которая мне нужна, заключается в следующем: когда я убиваю контейнер, все, что было создано под ним, должно быть уничтожено. Не только прямые дети, но и их потомки.
Когда я начинал этот проект, я ошибочно полагал, что когда вы убиваете процесс, его дети тоже автоматически убиваются. Я искал совета у людей, у которых была такая же неправильная идея. Хотя возможно поймать сигнал и передать убийство детям, это не то, что я ищу здесь.
Я верю в то, чего я хочу достичь, потому что, когда вы закрываете xterm, все, что в нем работает, уничтожается, если оно не было nohup'd. Это включает осиротевшие процессы. Вот что я хочу воссоздать.
У меня есть идея, что то, что я ищу, включает в себя сессии Unix.
Если бы существовал надежный способ идентифицировать всех потомков процесса, было бы полезно иметь возможность отправлять им и произвольные сигналы. например, SIGUSR1.
SIGHUP
его непосредственным дочерним процессам. Стандартный обработчик сигнала зависания прерывает выполнение процесса, поэтому маршрут по умолчанию - убить всех потомков. Узнайте больше о процессах и группах процессов.Ответы:
Если вы отправите сигнал процессу, этот процесс будет уничтожен. Интересно, как слух, что убийство процесса также убивает другие процессы, начался, это кажется особенно нелогичным.
Однако существуют способы уничтожить более одного процесса. Но вы не будете посылать сигнал одному процессу. Вы можете уничтожить целую группу процессов , отправив сигнал на -1234, где 1234 - это PGID (идентификатор группы процессов), который является PID лидера группы процессов. Когда вы запускаете конвейер , весь конвейер начинается как группа процессов (приложения могут изменить это, вызвав
setpgid
илиsetpgrp
).Когда вы запускаете процессы в фоновом режиме (
foo &
), они находятся в своей собственной группе процессов. Группы процессов используются для управления доступом к терминалу; обычно только передняя группа процессов имеет доступ к терминалу. Фоновые задания остаются в том же сеансе , но нет возможности убить весь сеанс или даже перечислить группы процессов или процессы в сеансе, так что это мало поможет.Когда вы закрываете терминал, ядро отправляет сигнал
SIGHUP
всем процессам, которые имеют его в качестве управляющего терминала . Эти процессы формируют сеанс , но не все сеансы имеют управляющий терминал. Поэтому для вашего проекта одна возможность состоит в том, чтобы запустить все процессы в их собственном терминале, созданном с помощью скрипта , экрана и т. Д. Завершить процесс эмулятора терминала, чтобы уничтожить содержащиеся в нем процессы (при условии, что они не были переданыsetsid
).Вы можете обеспечить большую изоляцию, запустив процессы под своим собственным пользователем, который больше ничего не делает. Тогда легко убить все процессы: запустить
kill
( системный вызов или утилиту ) от имени этого пользователя и использовать -1 в качестве аргумента PID для уничтожения, что означает «все процессы этого пользователя».Вы можете обеспечить еще большую изоляцию, но с гораздо большей настройкой, запустив содержащиеся процессы в реальном контейнере .
источник
prctl(PR_SET_PDEATHSIG, SIGHUP);
больше информации: man7.org/linux/man-pages/man2/prctl.2.htmlВнутри родительского скрипта перехватите сигнал kill и убейте всех детей. Например,
источник
Надежный способ идентифицировать всех потомков процесса - использовать команду,
pstree <pid>
где pid - это идентификатор вашего родительского процесса.Прочитайте справочную страницу
pstree
здесь .Чтобы сообщить всем членам группы процессов:
killpg(<pgrp>, <sig>);
где pgrp - номер группы процессов, а sig - сигнал.
Чтобы дождаться детей в указанной группе процессов:
waitpid(-<pgrp>, &status, ...);
Альтернативой тому, что вы делаете, является запуск вашего контейнера процессов в новой оболочке bash. Создайте новую оболочку bash с помощью команды
bash
и запустите ваши процессы. Когда вы хотите, чтобы все процессы были завершены, выйдите из оболочки с помощью командыexit
.источник
использование
Если вы убьете
unshare
, все дочерние процессы (которыеyourprogram
могли появиться) будут уничтожены.Теперь это возможно с util-linux
2.32
; Я реализовал это вверх по течению . Для этого требуются пользовательские пространства имен (опция конфигурации ядраCONFIG_USER_NS=y
) или привилегии root. Смотрите также здесь .источник
Команда rkill из пакета pslist отправляет данный сигнал (или
SIGTERM
по умолчанию) указанному процессу и всем его потомкам:источник
Еще один вариант убить всех потомков оболочки:
jobs -p | xargs -n 1 pkill -P
источник