Каков наилучший способ закрыть эту группу процессов? - PullRequest
1 голос
/ 16 сентября 2010

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

PID   PGRP  SESN  PPID USER     TTY  CMD 
6553  6553  6553     1 root     ?        ./startserv
6554  6553  6553  6553 root     ?        expect -- /usr/bin/unbuffer ./srcds_run...
6555  6555  6555  6554 root     pts/1    /bin/sh ./srcds_run -autoupdate -game c...
6565  6555  6555  6555 root     pts/1    ./srcds_linux -autoupdate -game cstrike...

В этой ситуации я обычно вручную выполняю kill 6553 6555. Очевидно, я знаю свой собственный pid, но немного глупо кодировать что-то вроде «kill my pid + 2» (хотя кажется, что это [почти ] всегда работает. Помогите?

Ответы [ 5 ]

1 голос
/ 16 сентября 2010

Ни один из этих ответов не очень правильный - самый простой способ справиться с этим - поместить процессы в группу процессов (дочерние процессы наследуют родительскую группу процессов, поэтому ваши двоичные файлы с закрытым исходным кодом также должны быть хорошими) через getpgrp / setpgrp , затем убейте их всех одним махом через killpg , что гарантирует, что все они получат сигнал одновременно, без каких-либо условий гонки, которые позволили бы дочернему процессув нужное время раздвоился, чтобы сбежать.

0 голосов
/ 19 сентября 2010

В итоге мое решение было: получить pid ребенка, которого родитель разветвляет в рамках программы (ожидаемый процесс). Запишите этот pid в файл блокировки вместе с pid первого процесса. Напишите bash-скрипт, который ищет, у каких процессов есть родительский объект, имеющий pid второго процесса. Убейте первый процесс и идентификатор процесса, возвращенный скриптом bash. Все заканчивается чисто. Вполне возможно, что с этим методом лучше всего использовать команду killpg, я на это посмотрю.

0 голосов
/ 16 сентября 2010

Со страницы руководства системного вызова kill (2):

Если pid отрицателен, но не равен -1, sig отправляется всем процессам (кроме неопределенного набора системных процессов), чей идентификатор группы процессов равен абсолютному значению pid и для которого процесс имеет разрешение на отправку сигнала .

EDIT

(здесь я прошу разъяснений, но мне нужно место и форматирование, которых нет в области комментариев)

Таким образом, pstree будет печатать:

startserv --- expect --- /bin/sh --- srcds_linux

И группировка групп будет:

{startserv --- expect} --- {/bin/sh --- srcds_linux}

И с startserv вы хотите убить expect, /bin/sh и srcds_linux, но убийство expect не приводит к expect убийству его непосредственного потомка (намного меньше, чем группа, к которой относится этот ребенок) глава).

Еще несколько предложений

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

Обнажая, что вы можете попытаться просмотреть /proc/*/stat, чтобы построить дерево процессов, найти ваш expect процесс (вы уже знаете его pid), а затем убить его и всех его дочерних элементов. Это не идеально, так как это не атомарно (/ bin / sh может разветвлять еще несколько дочерних объектов или что-то в этом роде), но если вы хотите попытаться это перехватить, вы можете отправить все процессы в этом поддереве SIGSTOP, так как понимаете, что они находятся под поддеревом expect, чтобы стабилизировать это дерево. Тогда пошлите им всем более сильное убийство, возможно, сопровождаемое SIGCONT.

Более автоматический способ сделать это состоит в том, чтобы startserv создать псевдотерминал для запуска expect (и его потомков) и затем закрыть управляющую сторону псевдотерминала и надеяться, что все эти программы умрут на SIGHUP.

0 голосов
/ 16 сентября 2010

Кажется, что самый простой способ сделать это - просто использовать bash. Я могу просто захватить вывод ps axo pid, ppid. У меня уже есть первый процесс, который генерирует файл блокировки со своим pid, поэтому bash-скрипт сможет найти первый элемент с ppid родительского pid и отправить ему SIGTERM вместе с родителем.

0 голосов
/ 16 сентября 2010

Звучит как плохой дизайн.Зачем тебе это так?Будет ли для вашего startserv процесса более разумным запускать другие как дочерние процессы, и в этом случае убить их просто?Чего ты пытаешься достичь?

...