2010-09-16 4 views
1

У меня есть следующая группа процессов, которые необходимо программно завершить с помощью первого перечисленного процесса, который является программой C, которую я кодирую.Каков наилучший способ закрыть эту группу процессов?

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... 

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

+0

Убивает ли процесс 'expect' (6554 выше) убить своего ребенка (6555)? – bstpierre

+0

Можете ли вы рассказать о том, как выполняется «ожидание»? Полный argv, с комментариями о типах файлов и что-то особенное о fork ... exec, которое происходит. – nategoose

ответ

0

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

0

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

+0

Причина в том, что я только пишу верхний процесс. У остальных троих есть собственные умы, в основном закрытые. – conartist6

0

Из справочной системы пользователя 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 создать psudoterminal для запуска expect (и его потомков) на, а затем закрыть контрольный сторону psudoterminal и надеемся, что все эти программы умереть на SIGHUP.

+0

Но перечисленные процессы не имеют того же PGRP. 'ожидать' создает новую группу. – bstpierre

+0

pstree дает мне | -startserv --- expect --- srcds_run --- srcds_linux --- 3 * [{srcds_linux}] Мне не нужно беспокоиться о странных случаях, отправляя сигстер на 6555 (в этот случай) прекратит все процессы, которые были ребенком 6555 (а именно 6556). Killing (term) 6553 избавляется от 553 и 554. Итак, какой лучший способ получить число этого третьего перечисленного процесса, предполагая, что группировка процесса всегда будет одинаковой, и предполагая, что добавление двух будет глупо. – conartist6

0

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

1

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

+2

Но ожидание создает новый pg, о котором родитель не знает непосредственно. – bstpierre

Смежные вопросы