LINUX.ORG.RU

Вопрос по сигналам....


0

0

Здравствуйте, гуру. Не поможете в таком деле? Мне надо запустить два процесса, которые следили бы друг за другом, то есть если один из них каким-нибудь образом убивается (сигнал KILL), то второй его должен перезапустить. Один другого создаёт с помощью fork(). Как сделать, чтобы родитель перезапускал дочерний это очевидно - обрабатываем SIGCHLD, а вот как сделать, чтобы дочерний процесс мгновенно (с помощью сигнала) узнал о смерти родителя - этого не знаю. Я знаю, что дочернему процессу изначально не посылается никаких сигналов при смерти родительского. Меня интересует: можно ли изменить ситуацию, т.е. сделать так, чтобы при килянии злоумышленниками родителя посылался заданный (неважно какой, но не KILL) сигнал дочернему процессу. Заранее спасибо.

anonymous

IMHO, nikak v obshem sluchae....

Esli process-roditel' okazalsja liderom terminal'nogo seansa, to potomok poluchit SIGHUP.

Mozhno poprobovat' ispol'zovat' funkcii tipa _atexit() dlja posylki signala..

A voobshe, pravil'nee navernoe zabyt' o signalah i ispol'zovat' semaphory i shared memory.

BaT ★★★★★
()

Спасибо большое. Но если можно, то поподробнее о функции _atexit(), а то я ещё начинающий в юнихе. Её в перле можно вызывать? И не совсем понятно про терминальный сеанс: что это конкретно такое и как его организовать?

anonymous
()

Если процесс-родитель помирает то PPID=1 для всех сирот,
таким образом можно проверять PPID и как только он ==1,
делать чего то. Можно thread для этих целей завести или по таймеру, каждую секунду или чаще. Хотя конечно это не будет асинхронное
уведомдление, но зависит от конечной цели, если родитель умирает
1000 раз в секунду для разных детей, то это конечно не подходит.

ovsov
()

интересная задачка в том смысле, что ее можно решить несколькими способами и в каждом из них найдется свои плюсы и минусы. честно говоря, я противник использовать сигналы только для межпроцессного уведомления. но это в общем случае. бывает и так, что без них просто никуда. поэтому необходимо всегда иметь ввиду конкретный случай, конкретную задачку, чтобы сказать, какой из способов оптимальнее. некто BaT обратил вимание на функцию atexit(). что мол она поможет. ответ в этом случае такой: нет, не поможет. данная функция вызывается в том случае, если процесс самостоятельно делает return из main(), либо вызывает exit(). в остальных случаях (сигналы, вызов _exit()) функция exit() будет проигнорирована, т.к. то, что зарегистрировано с помощью atexit() это библиотечный код, который вызывается, как только выходишь за рамки main(), но еще не закончен процесс. по сигналу процесс останавливается ядром ОС (по крайней мере на это нужно ориентироваться, если писать переносимый код), поэтому функции, зарегистрированные с помощью atexit(), вызываться не будут. т.е. процесс просто умрет и об этом не узнать, если ждать уведомления от кода, зарегистрированного через atexit(). что касается совета, то я бы сделал более изящно (с моей точки зрения): создал с помощью pthread_create() в каждом процессе дополнительную нитку и посадил бы ее на waitpid() для процесса, от которого ожидаем смерти. по выходу из waitpid() можно получить очень широкую информацию о процессе, чье изменение статуса ожидали. вот и все пироги;) C уважением, proff.

proff
()

С waitpid было бы конечно изящно, кто спорит.
Но проблема в том, что waitpid позволяет
ждать только детей, а если это не дитя
говорит что детей нет, а в нашем случае
надо ждать смерти родителя (ужас то какой).

ovsov
()

Мне очень нравится вариант, предложенный proff, но я так и не понял: можно ли с помощью waitpid() ожидать умирания родителя (а следовательно и вообще любого процесса) или нет. Насколько я знаю, ожидание смерти дочерей производится с помощью wait(). Я не прав?

anonymous
()

что касается waitpid() - то действительно, как написано в man'e, она ожидает один или группу дочерних процессов. если существует обратное - то это особенности конкретной платформы и их имеет смысл обсуждать только в рамках этой платформы.
идем дальше:
1. что касается вопроса "тупо хочу узнать, жив ли процесс с известным мне pid" - то есть один железный способ: вызвать kill(0, pid), который в случае, если процесс с этим pid существует, вернет ноль (но сигнал не пошлет!!!), а если не существует - то ошибку.
2. что касается "как узнать статус (получить код возврата) любого процесса", то здесь нужно точно знать, что родитель - это не любой процесс, а процесс, входящий в ту же группу, в которую входит и текущий процесс (если только сам текущий процесс после своего рождения не стал лидером своей группы; но это нужно делать ручками и об этом обычно уже известно;)). на этом можно сыграть. как конкретно на этом можно сыграть - сказать не могу, таких проблем решать не приходилось, но то, что это сделать можно, уже есть определенная зацепка.
от себя хочется заметить: обычно, если встают подобного рода проблемы (т.е. проблемы, которые необходимо решать нетривиальным способом, с помощью выдумывания обходных путей), имеет место ошибка в проектировании. а это значит, что скорее всего дешевле найти ее и исправить, чем заниматься мозговым онанизмом, осложняя жизнь себе и тем, кто это все будет потом поддерживать.

proff
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.