Как проверить, является ли процесс с pid X зомби? - PullRequest
3 голосов
/ 25 октября 2009

Я получил PID процесса, и мне нужно проверить, является ли это зомби, используя системные вызовы POSIX в C. Как мне это сделать?

Проблема, с которой я столкнулся, заключается в том, что у меня есть процесс, и он разветвляется на многих детей, все дети исполняют execs, а иногда я хочу выполнить exec в фоновом режиме, поэтому я не могу ждать () детей, которые идут в фоновом режиме. Я мог бы ждать () периодически (один раз в моем основном цикле), но мне нужно знать, какие процессы являются зомби, чтобы процесс моего отца не зависал при ожидании детей, которые скоро не завершатся.

Если вам любопытно, я создаю оболочку Unix, и это в природе оболочки, чтобы дочерние процессы вели себя асинхронно.

Ответы [ 5 ]

5 голосов
/ 25 октября 2009

Вы не можете проверить, является ли процесс зомби с чистыми вызовами POSIX - кроме случаев, когда вы являетесь родительским процессом, и пожинаете его с помощью вызова wait family . Поэтому вам нужно найти хорошее место, чтобы ждать ребенка.

Один из вариантов - установить обработчик SIGCHLD и выполнить там waitpid(0, &status, WNOHANG). Обязательно зацикливайтесь, пока не перестанут обнаруживаться какие-либо процессы - если в течение короткого промежутка времени умирают двое детей, вы можете получить только один SIGCHLD.

Другим вариантом является двойная разветвление - fork(), чтобы дочерний элемент (назовите его дочерним A) снова разветвился, второй exec для дочернего элемента (дочернего элемента B). Тогда ребенок А сразу выходит. Тем временем родитель wait() запрашивает ребенка A. После того, как ребенка A нет, процесс инициализации системы позаботится о том, чтобы пожать ребенка B, когда он в конечном итоге умрет. Этот метод проще, но ваша оболочка не сможет узнать, когда умирает дочерний элемент B, поэтому, если вам нужна эта информация, используйте первый метод.

3 голосов
/ 25 октября 2009

Но ... но ... зомби - это ребенок (на каком-то уровне), а проверяемый процесс - это родитель, верно? Так что, если вы обеспокоены тем, что конкретный pid является зомби, почему бы просто не сделать waitpid(2) с WNOHANG и избавиться от него? Теперь это будет использовать состояние выхода, поэтому может быть плохой идеей, если какой-то другой процесс захочет действительно wait в будущем.

1 голос
/ 25 октября 2009

Обычно оболочка проверяет наличие недееспособных дочерних элементов незадолго до печати своего приглашения - используя системный вызов waitpid(2) и параметр WNOHANG, как уже обсуждалось. Вы также можете захотеть обработчик SIGCHLD - но вам придется решить, что вы будете делать с информацией, если вы заняты ожиданием завершения какого-либо процесса переднего плана, и это фактически фоновый процесс, который завершается.

Это лишь незначительное изменение выбранного в данный момент ответа.

1 голос
/ 25 октября 2009

Вы упоминаете, что вы создаете оболочку Unix; Вы должны прочитать это: Правильное обращение с SIGINT / SIGQUIT

0 голосов
/ 16 декабря 2014

А как насчет команды оболочки 'ps', которая показывает вам таблицу активных процессов, где вы можете обнаружить, что процесс 'не существует'? Я полагаю, что должен быть способ получить эту информацию из кода c.

...