LINUX.ORG.RU

fork + execv = zombie


0

0

Ситуация следующая,
есть процесс родительский, который изначально делает fork,
потом в потомке загружает другой процесс(дочерний).
Родительский процесс открывал сокет, создавал дочерний процесс,
потом закрывал его. Дочерний процесс перед exit(0), тоже закрывает его.
В результате, после того, как в дочернем процессе вызываеться
exit(0), он остаеться зомби, что не есть хорошо.
Из за чего подобное может случиться?

anonymous

Родителю нужно обрабатывать, либо игнорировать сигнал о смерти потомка SIGCHLD. Тогда все будет ОК.

anonymous
()
Ответ на: комментарий от nobody

>>А wait(2) в родителе не делал?
Нет, потомок сам принимает решение что ему нада помереть,
либо сокет, который он обрабатывает, дисконектнулся,
либо получил сообщение из того сокета, что все, сессия окончена.


anonymous
()
Ответ на: комментарий от anonymous

>>Родителю нужно обрабатывать, либо игнорировать сигнал о смерти >>потомка SIGCHLD. Тогда все будет ОК

Сделал, помогло, а ПОЧЕМУ? Ткни пожалуйчта, где почитать.

anonymous
()

зомби - это не процесс, а запись в таблице процессов, оставшаяся от умершего процесса. Пока родитель не получит информацию о статусе его завершения - она из таблицы не уйдет.

SadStork
()
Ответ на: комментарий от SadStork

>>Пока родитель не получит информацию о статусе его завершения - она
>>из таблицы не уйдет.

А почему тогда помогает игнорирование SIGCHLD?
Дефолтовый обработчик не готов к тому, что порожденный процесс
сам может захотеть помереть?

anonymous
()

Как все это устроено:

Ты говоришь ядру: создай процесс.
Ядро создает запись в таблице процессов.
После этого процесс начинает выполняться.
Когда процесс умирает, запись в таблице ядра остается.
В ней, помимо прочего, записан код завершения процесса.
Родитель вызовом wait(2) получает этот код.
После этого ядро удаляет запись об умершем процессе.
Пока не вызван wait, запись не удаляется.
Процесса нет, а запись есть -- это зомби.
Если родитель умирает раньше потомка, то потомок отдается init'у.
В этом случае wait должен будет вызвать init.
Узнать подробности можно по команде `man 2 wait'.

А игнорировать SIGCHLD нежелательно.
Вот что говорит по этому поводу `man sigaction':

POSIX (B.3.3.1.3) disallows setting the action for SIGCHLD
to SIG_IGN. The BSD and SYSV behaviours differ, causing
BSD software that sets the action for SIGCHLD to SIG_IGN
to fail on Linux.

nobody ★★
()
Ответ на: комментарий от anonymous

Хорошо, а можно сказать системе что мне нафиг не нужно знать умер мой потомок или нет перед запуском его или после запуска ?

anonymous
()

signal(SIGCHLD,SIG_IGN) - говорилось же уже раза два

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