Я согласен с общим настроением caf : если процесс вызывает setsid
, он говорит, что хочет жить самостоятельно, несмотря ни на что.Вы должны тщательно продумать, действительно ли вы хотите их убить.
При этом иногда требуется, чтобы какая-то форма "суперсессии" содержала дерево процессов.В наборе инструментов POSIX нет такого инструмента, который бы предоставлял такие супер-сессии, но я собираюсь предложить несколько решений.Каждое решение имеет свои ограничения, поэтому, скорее всего, они не будут применимы к вашему случаю, но, надеюсь, одно из них подойдет.
Чистое решение - запускать процессы в своей виртуальной среде.,Это может быть jail в стиле FreeBSD, Linux cgroups или любой другой вид технологии виртуализации.Ограничения этого подхода заключаются в том, что технологии виртуализации зависят от ОС, и процессы будут работать в несколько ином контексте.
Если у вас есть только один экземпляр этих процессов в системе, и вы можете подключиться к корню, запустите процессы как выделенный пользователь.Супер-сеанс определяется как процессы, выполняемые как выделенный пользователь.Убейте потомков с помощью kill(-1, signum)
(обратите внимание, что это убьет сам процесс-убийцу, если он не заблокирован или не обработал сигнал).
Вы можете сделать процесс открытым уникальным файлом, убедившись, что флаг FD_CLOEXEC
устанавливается в дескрипторе файла.Все дочерние процессы будут наследовать открытый файл, если они явно не уберут флаг FD_CLOEXEC
перед вызовом execve
или не закроют файл.Убить процессы с помощью fuser -k
или получить список идентификаторов процессов с помощью fuser
или lsof
(fuser
в POSIX, но не fuser -k
.) Обратите внимание, что существует условие гонки: процесс может быть разветвлен междувремя, когда вы звоните fuser
, и время, когда вы убиваете его;поэтому вам нужно вызывать fuser
в цикле до тех пор, пока больше не появятся процессы (не повторяйте цикл, пока все процессы не будут остановлены, поскольку это может быть бесконечный цикл, если один из процессов блокирует ваш сигнал).
Вы можете сгенерировать уникальную случайную строку и определить переменную окружения с этим именем или с хорошо известным именем и этой уникальной строкой в качестве значения.Он будет унаследован всеми процессами-потомками, если они не решат изменить свою среду.Не существует портативного способа поиска процессов на основе их среды или даже получения среды другого процесса.Во многих вариантах Unix вы можете получить информацию с опцией ps
(например, ps -e
на * BSD или ps e
на Linux);Анализ информации может быть непростым, но наличие уникальной строки является достаточным показателем.Как и в случае с fuser
выше, обратите внимание на необходимость цикла, чтобы избежать состояния гонки, если потомок вызывает fork
слишком поздно, чтобы вы заметили его потомка, но прежде чем вы смогли убить родителя.
Вы можете LD_PRELOAD
небольшая библиотека, которая разветвляет поток, который прослушивает канал связи, и убивает его процесс при получении уведомления.Это может нарушить процесс, если он ожидает узнать обо всех своих собственных потоках;Это возможно только в архитектурах, где стандартная библиотека всегда поточно-ориентирована, и вы пропустите статически связанные процессы.Канал связи может быть любым, что позволяет главному процессу транслировать порядок самоубийства;одна возможность - канал, где каждый процесс-потомок выполняет блокирующее чтение, а процесс-предок закрывает канал, чтобы уведомить потомков.Передайте номер дескриптора файла через переменную окружения.