LINUX.ORG.RU

Невыход по exit()


0

0

Чертовщина какая-то...

кусок выглядит упрощенно так:

while(1)
{
rc = fork()
if(rc==0) //типа ребенок
{
some_function();
exit(EXIT_SUCCESS);
}
else
{
//parent_to_do...
}
}//while
Процесс-папенька висит как демон сам, все нормально, потомок выполняет функцию (корректно) и пытается выйти. (статус - RE)... а вот не выходит. Перехвата сигналов нет, процессом-родителем установлена setsid()... ничего не понимаю...
Потомки мрут только после выхода родителя. В чем дело?

anonymous

попробуйте waitpid с WNOHANG время от времени вызывать

anonymous
()

Так и должно быть. Потомок когда вызывает exit(), становится зомби(т.е. занимает в таблице процессов запись), а вот когда родитель завершается, потомок будет уноследован init и прибъет его. Поэтому чтобы зомби не плодились нужно вызывать wait(waitpid) или самому обрабатывать SIGCHLD(sigaction, signal).

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

Всем спасибо. Проблема решена: signal(SIGCHLD, SIG_IGN); - игнор сигналов от потомков, отчего они выходят, не превращаясь в зомби.

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

Лучше уж обрабатывайте сигнал SIG_CHLD, так как Ваше решение соответствует только SystemV и "наследникам". По стандарту POSIX нужно обрабатывать сигналы самому. Можно конечно забить на это, но если будешь переносить программу в другую ОС можно получить неожиданные "эффекты".

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

Ну, работает на всех юниксах, начиная с 5.3 - раньше еще не смотрела. В любом случае, всю систему уже трудно перенести на другую платформу.

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

anonymous (*) (12.12.2005 13:27:16):

> Ну, работает на всех юниксах, начиная с 5.3

Хорошо сказала! ;)

На самом деле, это -- не кошерно.

То есть, это все будет работать под Линуксом -- _сегодня_. Но нет гарантии, что _в_будущем_ это все так и останется. В последние годы Линух совершенно перестал быть сам с собой совместимым, семантика базовых вызовов постоянно меняется от версии к версии ядра и либЦе.

Данное место как раз одно из самых запутанных. Существует масса различных стандартов, и даже POSIX уже менялся.

Можно делать неблокирующий wait() в обработчике SIGCHLD.

Если время старта дочки не шибко критично, то надежнее всего ее слегка "демонизировать", то есть передать дочку init'у.

Die-Hard ★★★★★
()
Ответ на: комментарий от Die-Hard

> На самом деле, это -- не кошерно.

хм... ну ладно, это вопрос вкуса :)

> В последние годы Линух совершенно перестал быть сам с собой
> совместимым

вообще-то для linux kernel совместимость на user-level назад -
это просто священная корова. большинство "поломок" происходит
в libc.

> семантика базовых вызовов постоянно меняется от
> версии к версии ядра

да не может такого быть! пример?

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

idle

>> семантика базовых вызовов постоянно меняется от > версии к версии ядра

> да не может такого быть! пример?

Ну, в принципе, насчет "ядра" я погорячился, пожалуй. Я держал в голове sched_yield(), который меня ДОСТАЛ, но это, скорее, из области багофич -- "официально" семантика не меняется.

Еще навскидку вспоминается история с sendfile() file->file, но там, вроде, тоже просто баг был.

Но сисколлов ж мы прямо не дергаем: все в либЦе завернуто. А она в последние годы -- просто ужас...

Die-Hard ★★★★★
()
Ответ на: комментарий от Die-Hard

Отвечу совершенно по-женски: когда либся изменится настолько, чтоб по-другому обрабатывать action сигналов - я буду уже далеко :), с меня не спросят... :)))))))))

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

anonymous (*) (12.12.2005 17:55:46):

:-)

Да нет, все нормально. Игнорировать SIGCHLD, если не интересуешься детками после рождения, является общепринятой практикой.

Просто IMHO не лишним будет отдавать себе отчет, что эта практика за последние 10 лет уже пару раз менялась.

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