Russian Qt Forum

Компиляторы и платформы => Linux => Тема начата: spectre71 от Июнь 25, 2009, 10:55



Название: Как терминировать процесс со всеми его потомками в Linux(Mac)
Отправлено: spectre71 от Июнь 25, 2009, 10:55
Есть приложение запускающее процессы(различные консольные программы) из под себя.
Процесс запускаемый непосредственно данным приложением будем называть Родительским.
Родительским процесс в свою очередь может запускать из-под себя другие процессы, которуе в свою очередь так же могут запускать процессы,
назовем все процессы порожденные Родительским прямо или косвенно Дочерними.
Приложению не известно создаются ли Дочернии процессы Родительским.

Приложение в любой момент может убить Родительский процесс. Задача убить все его Дочернии процессы.

Под Windows данная задача решена. Создаем JobObject (CreateJobObject(...)), далее после создания Родительского процесса в SUSPENDED режиме делаем AssignProcessToJobObject, и делаем ResumeThread для гланого потока Родительского процесса. Теперь если наш Родительский процесс породит какие-либо Дочернии процессы, они будут автоматически ассоциированы с JobObject. Теперь при терминировании JobObject все ассоциированные с ним процессы будут терминированы! Причем вне зависимости завершился ли Родительский процесс или завис или еще чего.

Как решить эту задачу под Linux(Mac) я не нашел. Может в Linux(Mac) вообще такой возможности нет?
Помогите знающие люди!



Название: Re: Как терминировать процесс со всеми его потомками в Linux(Mac)
Отправлено: Авварон от Июнь 25, 2009, 11:25
в линуксе есть такая штука как "группа", причем, если мне не изменяет память то сигнал рассылается всей группе => нужно слать сигнал родителю (если надо, могу откопать коды 2ого курса где нас учили работать с процессами, если помнится то в shell'е, к-ый нас заставляли писать как раз была смена группы чтоб не гробить процессы в бекграунде по SIGTERM самому шеллу)


Название: Re: Как терминировать процесс со всеми его потомками в Linux(Mac)
Отправлено: spectre71 от Июнь 25, 2009, 11:33
в линуксе есть такая штука как "группа", причем, если мне не изменяет память то сигнал рассылается всей группе => нужно слать сигнал родителю (если надо, могу откопать коды 2ого курса где нас учили работать с процессами, если помнится то в shell'е, к-ый нас заставляли писать как раз была смена группы чтоб не гробить процессы в бекграунде по SIGTERM самому шеллу)
С группами я пытался разобраться, но так и не понял как применить их к моей задаче, если знаешь помоги!
С другой стороны слать сигнал родителю точно безсмысленно, пример:
Родитель порождает Дочерний процесс и сразу завершается, а Дочерний процесс продолжает работать.


Название: Re: Как терминировать процесс со всеми его потомками в Linux(Mac)
Отправлено: kuzulis от Июнь 25, 2009, 11:41
а нельзя например родителю, когда он создаёт потомство - как то узнать PID этих потомков.. и потом если вдруг он завершается - то по этим PID - ам происходит kill  (например в деструкторе родителя) ???
не? или я опять костыль придумал? :)


Название: Re: Как терминировать процесс со всеми его потомками в Linux(Mac)
Отправлено: Авварон от Июнь 25, 2009, 11:50
а родитель како-то левый или тобой написанный?


Название: Re: Как терминировать процесс со всеми его потомками в Linux(Mac)
Отправлено: spectre71 от Июнь 25, 2009, 11:54
а нельзя например родителю, когда он создаёт потомство - как то узнать PID этих потомков.. и потом если вдруг он завершается - то по этим PID - ам происходит kill  (например в деструкторе родителя) ???
не? или я опять костыль придумал? :)
Смешно!
Родитель запущенный процесс - любая консольная программа! Какой может быть деструктор родителя


Название: Re: Как терминировать процесс со всеми его потомками в Linux(Mac)
Отправлено: spectre71 от Июнь 25, 2009, 11:56
а родитель како-то левый или тобой написанный?
Любая консольная программа и для моего приложения - черный ящик!


Название: Re: Как терминировать процесс со всеми его потомками в Linux(Mac)
Отправлено: Авварон от Июнь 25, 2009, 12:13
гм, ну если известен процесс, то пид можно получить через ps. аналогично через нее же можно выцепить и все прцессы с ппидом, равным пиду родительского и пригробить их поштучно...
а группы немного не то, или я чего-то не понимаю)


Название: Re: Как терминировать процесс со всеми его потомками в Linux(Mac)
Отправлено: spectre71 от Июнь 25, 2009, 12:28
гм, ну если известен процесс, то пид можно получить через ps. аналогично через нее же можно выцепить и все прцессы с ппидом, равным пиду родительского и пригробить их поштучно...
а группы немного не то, или я чего-то не понимаю)
В общем случае невозможно!
1) Неизвестены моменты запуска Дочерних процессов.
2) Пид родителя у Дочернего может сменниться, и ситуаций здесь много, пример:
Родитель в какой-то момент порождает Дочерний процесс и быстро завершается, а Дочерний процесс продолжает работать.
Даже если постоянно мониторить пиды(что очень накладно), можно промазать и пропустить момент - порождение Дочернего+изменение у него  пида родителя.


Название: Re: Как терминировать процесс со всеми его потомками в Linux(Mac)
Отправлено: kuzulis от Июнь 25, 2009, 13:06
а если почитать про принцип формирования PID-ов в линуксе и уже исходя от этого плясать?

1. есть ли какая нить закономерность в PID-ах родителя и дочерних? т.е. можно как-то узнать по PID-у какго нить выборочного процесса, кто его родитель??
2. если так можно, то приложение при запуске своего процесса просто запоминает его PID... и если вдруг оно "прибивает" этот процесс, то
 с помошью ps можно найти все PID-ы дочерних и поддочерних и подподдочерних процессов (например по маске или как нить так - я хез, нужно читать про ps, kill и т.п.)  и прибить их все! :)

Но это если все-таки есть какая-то связь м\у PID ами (я хез ) :)

можно и так как говорит Авварон , например после прибития главного процесса - в течении определенного времени мониторить систему и прибивать дочерние процессы которые создают новые и новые!!! :) например в течении 30 секунд и т.п. 

ЗЫ: и тут хто его знает кто победит - или живучие дочерние, которые постоянно рожают новых.. или твое приложение, которое их прибивает :)


Название: Re: Как терминировать процесс со всеми его потомками в Linux(Mac)
Отправлено: spectre71 от Июнь 25, 2009, 13:21
Я только-что писал:
В общем случае невозможно!
1) Неизвестены моменты запуска Дочерних процессов.
2) Пид родителя у Дочернего может сменниться, и ситуаций здесь много, пример:
Родитель в какой-то момент порождает Дочерний процесс и быстро завершается, а Дочерний процесс продолжает работать.
Даже если постоянно мониторить пиды(что очень накладно), можно промазать и пропустить момент - порождение Дочернего+изменение у него  пида родителя.

Если Пид родителя у Дочернего сменился его не найти!!!


Название: Re: Как терминировать процесс со всеми его потомками в Linux(Mac)
Отправлено: kuzulis от Июнь 25, 2009, 13:23
А как он сменится? о_О он же вроде всегда один и тот же..  процесс запустили, пид присвоился и все.... и с этим пидом он и буит "всю жизнь" пока не прихлопнут.. не?


Название: Re: Как терминировать процесс со всеми его потомками в Linux(Mac)
Отправлено: spectre71 от Июнь 25, 2009, 13:29
А как он сменится? о_О он же вроде всегда один и тот же..  процесс запустили, пид присвоился и все.... и с этим пидом он и буит "всю жизнь" пока не прихлопнут.. не?
Ничего подобного.
По Linux если родительский процесс завершился тем или иным образом, все его дочерние перепривязываются к какому-то там системному процессу.


Название: Re: Как терминировать процесс со всеми его потомками в Linux(Mac)
Отправлено: Авварон от Июнь 25, 2009, 14:12
к иниту, процессу с номером 1...


Название: Re: Как терминировать процесс со всеми его потомками в Linux(Mac)
Отправлено: spectre71 от Июнь 25, 2009, 14:30
к иниту, процессу с номером 1...
Именно!
Вот по этому и нужен некоторый системный механизм для регистрации(или группировки) всех Дочерних процессов.
Для Windows это делается через JobObject.
Что делать под Linux?


Название: Re: Как терминировать процесс со всеми его потомками в Linux(Mac)
Отправлено: ритт от Июнь 25, 2009, 15:28
бла-бла-бла...
какое отношение данный тред имеет к Qt?


Название: Re: Как терминировать процесс со всеми его потомками в Linux(Mac)
Отправлено: spectre71 от Июнь 25, 2009, 16:54
бла-бла-бла...
какое отношение данный тред имеет к Qt?
Ну прямого отношения может и не имеет.
Переписываю приложение с C++ Builder(Windows) на QT(Windows, Linux, Mac).
QProcess мне не обеспечивает необходимой фукциональности.
Под Windows проблема решена.
Необходимо решить для  Linux и Mac.


Название: Re: Как терминировать процесс со всеми его по
Отправлено: Blayder от Июль 20, 2009, 00:41
Код:
killall -h
Usage: killall [OPTION]... [--] NAME...
       killall -l, --list
       killall -V, --version

  -e,--exact          require exact match for very long names
  -I,--ignore-case    case insensitive process name match
  -g,--process-group  kill process group instead of process
  -i,--interactive    ask for confirmation before killing
  -l,--list           list all known signal names
  -q,--quiet          don't print complaints
  -r,--regexp         interpret NAME as an extended regular expression
  -s,--signal SIGNAL  send this signal instead of SIGTERM
  -u,--user USER      kill only process(es) running as USER
  -v,--verbose        report if the signal was successfully sent
  -V,--version        display version information
  -w,--wait           wait for processes to die

man killall (http://linux.die.net/man/1/killall)
Может это?


Название: Re: Как терминировать процесс со всеми его по
Отправлено: spectre71 от Июль 20, 2009, 10:38
man killall (http://linux.die.net/man/1/killall)
Может это?

Нет, почитай тему с начала.


Название: Re: Как терминировать процесс со всеми его потомками в Linux(Mac)
Отправлено: Blayder от Июль 20, 2009, 20:00
прочитал тему сначала...
например:
(http://img39.imageshack.us/img39/2272/htop.th.png) (http://img39.imageshack.us/i/htop.png/)
видим древо просессов запущенных от xdm и если сейчас выполнить команду, например:
killall -s 64 -g xdm
 - это отправит сигнал SIGKILL xdm'у и всем дочерним от него запущенным.
А то, как вы писали, что родительский процесс запускает дочерний и тут же сам завершается... Не делает ли это дочерний процесс уже родительским?
Ибо как ни крути, ведь все процессы являются дочерними для ini...

Может еще можно как-то мониторить /proc используя демон fam(file alteration monitor)... Ведь в /proc хранится вся инфа по процессам в директориях под названием PID каждого процесса...

Или всетаки каким-то образом мониторить древо процессов, используя, как вариант, команду:
ps axjf


Название: Re: Как терминировать процесс со всеми его потомками в Linux(Mac)
Отправлено: spectre71 от Июль 20, 2009, 20:14
...
А то, как вы писали, что родительский процесс запускает дочерний и тут же сам завершается... Не делает ли это дочерний процесс уже родительским?
...
Читай внимательней, это уже обсуждалось!
Я уже писал про это выше, но повторю. В общем случае при мониторинге дочерних процессов можно пропустить нужный  интервал!
Один из примеров(подобных проблем несколько!)

Потомка еще нет.......
Мониторим......
Потомка еще нет.......
Мониторим......
Потомка еще нет.......
начало пропущенного интервала(между мониторингами) [
1) Родитель создал дочерний процесс
2) Родитель отвалился
3) Дочерний процесс перепривязался к ini
] конец пропущенного интервала
Потомка проморгали.......
Домониторились......


Название: Re: Как терминировать процесс со всеми его по
Отправлено: Blayder от Июль 20, 2009, 20:34
я чет теряю мысль...
Вам надо было убить родителя и всех его потомков?
Или выслеживать когда и как родитель создает потомков?
был родитель и родил дочерний:
PID         NAME
1              ini
300          + родитель
320                +-- дочерний
родитель умер, остался дочерний:
PID         NAME
1              ini
320           +-- дочерний

разве дочерний не стал родителем?


Название: Re: Как терминировать процесс со всеми его по
Отправлено: spectre71 от Июль 20, 2009, 20:51
я чет теряю мысль...
Вам надо было убить родителя и всех его потомков?
Или выслеживать когда и как родитель создает потомков?
был родитель и родил дочерний:
PID         NAME
1              ini
300          + родитель
320                +-- дочерний
родитель умер, остался дочерний:
PID         NAME
1              ini
320           +-- дочерний

разве дочерний не стал родителем?


А откуда я узнаю PID  дочернего чтобы его убить если родитель родитель(какого либо уровня отвалился)?       
И схема не такая:

1              ini
280          + MyAPP - который создает родителя
300              + родитель
320                  +-- дочерний

При мониторенге можно проморгать дочерний, что недопустимо(одна из ситуаций описана выше)!


Название: Re: Как терминировать процесс со всеми его по
Отправлено: Blayder от Июль 20, 2009, 21:24
ну мониторим мы древо:
первый снапшот дерева допустим имеет структуру:
PID         NAME
1              ini
280          + MyApp
300             + родитель

тут на монитор делает паузу и рождается дочерний и отмирает родитель:

PID         NAME
1              ini
280          + MyApp
320             + Дочерний

Врубается наш монитор и делает снапшот древа и видит, что новый снапшот не совпадает со старым, сопоставляет и видит - агаа...
Пропал процесс с пидом 300 и появился процесс с пидом 320...
Но в такой ситауции вы разумеется не будете знать откуда этот новый процесс породился... НО.. а надо оно вам?
пусть родиль нашей дочурки и пропал, однако ведь древо не изменилось - родитель у них так и остался MyApp... и при киле MyApp - умрет и дочурка...
Ну конечно, если случится неимоверное судо и дочурка не вырвется из MyApp и не прилипнет в ini...
Но даж в такой ситуации:
PID         NAME
1              ini
280          + MyApp
320          + Дочерний
Разве сравнив в спредыдущим снапшотом древа:
PID         NAME
1              ini
280          + MyApp
300             + родитель
мы не увидим, что изменилась связь в древе и пид 320 изменил своего родителя?
??? хотя откуда нам знать чей он аще был, если он изниоткуда вылез  ???
Хмм... тут в общем надо штудировать действия процессов и возможные исходы при смерти родителя... То, как он решает куда цепляться... К следущему родителю уровнем выше, либо же сразу к корню...
догадки, догадки...

П.С. может подскажите вариант как можно такое повидение сэмитировать? с радостьюб проверил и помог :-D
П.П.С. Сигнал pdeath_signal используется когда процесс лишается "родителя" (в случае его "смерти") и может быть получен/установлен посредством команд PR_GET/SET_PDEATHSIG системного вызова prctl(2) - http://www.opennet.ru/docs/RUS/lki/lki-2.html#ss2.2


Название: Re: Как терминировать процесс со всеми его потомками в Linux(Mac)
Отправлено: spectre71 от Июль 20, 2009, 21:33
Эсли бы было так, все было бы просто :)
1              ini
280          + MyAPP - который создает родителя
300              + родитель
320                  +-- дочерний

если отваиться родитель то будет не так
1              ini
280          + MyAPP - который создает родителя
320              +-- дочерний

а так:

1              ini
280          + MyAPP - который создает родителя
320          + дочерний - (привязан к ini)



Название: Re: Как терминировать процесс со всеми его потомками в Linux(Mac)
Отправлено: lit-uriy от Июль 20, 2009, 21:47
>>а так:
>>...
Это почему? недолжен процесс через дедушку к прадедушке перескакивать


Название: Re: Как терминировать процесс со всеми его потомками в Linux(Mac)
Отправлено: spectre71 от Июль 20, 2009, 22:05
>>а так:
>>...
Это почему? недолжен процесс через дедушку к прадедушке перескакивать
Он перескакивает не к прадедушке а к процессу "ini", есть такой в Unix. Под виндой примерно так же. Так сделаны операционки, не вдавался в подробности но видимо есть на то причины.


Название: Re: Как терминировать процесс со всеми его потомками в Linux(Mac)
Отправлено: Blayder от Июль 20, 2009, 23:00
Цитировать
Таким образом, все процессы в UNIX связаны отношениями процесс-родитель - процесс-ребенок, образуя генеалогическое дерево процессов. Завершение процессов в лекцииДля сохранения целостности генеалогического дерева в ситуациях, когда процесс-родитель завершает свою работу до завершения выполнения процесса-ребенка, идентификатор родительского процесса в данных ядра процесса-ребенка (PPID - Parent Process IDentificator) изменяет свое значение на значение 1, соответствующее идентификатору процесса init, время жизни которого определяет время функционирования операционной системы. Тем самым процесс init как бы усыновляет осиротевшие процессы. Наверное, логичнее было бы изменять PPID не на значение 1, а на значение идентификатора ближайшего существующего процесса-прародителя умершего процесса-родителя, но в UNIX почему-то такая схема реализована не была.
Да, вы были правы... при смерти родителя - дочерние сразу лепятся в иниту без вопросов "а кто там мой дедушка" и т.д.
http://cs.mipt.ru/docs/courses/osstud/03/prep/sem3-4.htm#s0304


Название: Re: Как терминировать процесс со всеми его потомками в Linux(Mac)
Отправлено: break от Июль 21, 2009, 00:56
Если бы в линукс был полный лог создания PID-ов(я не в курсе существует ли такой) то вам нужно было бы его использовать, тем не менее эта сложноватое решение на мой взгляд...
Может все же подойдет ситуация когда имеется список имен процессов кот. в определенный момент ищутся и прибиваются. Конечно так можно убить что-то лишнее что никогда родителем не создавалось.. Просто то чего не реализовали в ОС вам реализовывать в программе не самый простой путь...


Название: Re: Как терминировать процесс со всеми его потомками в Linux(Mac)
Отправлено: spectre71 от Июль 21, 2009, 09:27
Просто то чего не реализовали в ОС вам реализовывать в программе не самый простой путь...

В виндах есть для этих целей(и не только для них) JobObject.
В Linux насколько понимаю что-то связанное с группами?


Название: Re: Как терминировать процесс со всеми его потомками в Linux(Mac)
Отправлено: Авварон от Июль 21, 2009, 09:56
не, судя по тому что я читал, когда тема была только создана - группа процесса - это просто наследование группы владельца.