Есть демон который плодит дочек при соединении к нему клиента, после разсоединения дочка закрывается и превращается в зомби. Подскажите как написать обработчик сигнала закрытия? Ато во всех доках которые я нашёл используется wait, но мне нельзя ждать, мне нужно чтоб демон бодоствовал.Спасибо!
В главном цикле, который крутит главный процесс, поставь такой текст (должен периодически выполняться):pid_t pid;
while( (pid = waitpid(-1,0,WNOHANG)) > 0 )
;
>В главном цикле, который крутит главный процесс, поставь такой текст (должен периодически
>выполняться):
>
>pid_t pid;
>while( (pid = waitpid(-1,0,WNOHANG)) > 0 )
> ;
Спасибо, попробую.
>В главном цикле, который крутит главный процесс, поставь такой текст (должен периодически
>выполняться):
>
>pid_t pid;
>while( (pid = waitpid(-1,0,WNOHANG)) > 0 )
> ;Попробовал непомогло:
while(1){
// waitpid(-1,0,WNOHANG); - пробовал и так
while( (pid_ = waitpid(-1,0,WNOHANG)) > 0 )
;
newsid=accept(sid, (struct sockaddr *)&remoteAddr, &sin_size);
if(newsid==-1){
syslog(LOG_ERR,"Accept error");
closelog();
exit(1);
}
if (!fork()){
syslog(LOG_INFO,"Got a connection from %s",inet_ntoa remoteAddr.sin_addr));
close(sid);
talker(newsid, remoteAddr);
close(newsid);
syslog(LOG_INFO,"Close connection from %s",inet_ntoa(remoteAddr.sin_addr));
closelog();
exit(0);
}
}
}Всёравно зомби остается.
Что делать?
А ты уверен, что у тебя waitpid регулярно выполняется? На accept не блокируется случайно.
Механизм 100% рабочий.
>А ты уверен, что у тебя waitpid регулярно выполняется? На accept не
>блокируется случайно.
>Механизм 100% рабочий.
Точно блокируется!Спасибо!
>Есть демон который плодит дочек при соединении к нему клиента, после разсоединения
>дочка закрывается и превращается в зомби. Подскажите как написать обработчик сигнала
>закрытия? Ато во всех доках которые я нашёл используется wait, но
>мне нельзя ждать, мне нужно чтоб демон бодоствовал.
>
>Спасибо!Обрабатывай SIGCHLD и вызывай wait там
Отлов и обработка SIGCHLD - геморное занятие, но главное - это наличие многих ограничений в функции-обработчике сигналов. Также теоретически никто не гарантирует:
1.своевременной доставки сигнала
2.вообще доставки сигнала
3.вместо несколько одинаковых последовательных сигналов может придти один
>Отлов и обработка SIGCHLD - геморное занятие, но главное - это
>наличие многих ограничений в функции-обработчике сигналов. Также теоретически никто не
>гарантирует:
>1.своевременной доставки сигнала
>2.вообще доставки сигнала
>3.вместо несколько одинаковых последовательных сигналов может придти один
А ты не пользую ту ОС, где не гарантируют =)
Это настолько теоретически, как и wait не дождется потомка, или сорвется во время получения сигнала - в линухе, в отличии от freeBSD системные вызовы не возобнавляются.
>А ты не пользую ту ОС, где не гарантируют =)
А может сразу и аппаратку на нескольких тысячах компов сменить?>Это настолько теоретически, как и wait не дождется потомка, или сорвется во
>время получения сигнала - в линухе, в отличии от freeBSD системные
>вызовы не возобнавляются.
Зачем надеятся на удачу, если есть более надежное и более простое решение?
>Отлов и обработка SIGCHLD - геморное занятие, но главное - это
>наличие многих ограничений в функции-обработчике сигналов. Также теоретически никто не
>гарантирует:
>1.своевременной доставки сигнала
>2.вообще доставки сигнала
>3.вместо несколько одинаковых последовательных сигналов может придти один
Ну, насчет отлова sigchld и wait, это все сделано насколько возможно надежно, иначе я думаю, при той же сборке мира с -j16 зомби бы хоть один, но появился, однако же такого не наблюдается.
>Ну, насчет отлова sigchld и wait, это все сделано насколько возможно надежно,
>иначе я думаю, при той же сборке мира с -j16 зомби
>бы хоть один, но появился, однако же такого не наблюдается.Так я не против... Но есть описание механизма работы сигналов. Читаем и делаем выводы...
Какая мне разница, что где-то зомби не остаются? Народ вот тут и delete для одного указателя по два раза вызывает и убеждает, что все типа работает. Что из этого? Есть правила, стандарт. Хотим - пользуемся, не хотим - не пользуемся...Скажите, что проще - тот текст, который я привел (Стивенс) или отлов сигналов? Зачем усложнять себе жизнь?
>Скажите, что проще - тот текст, который я привел (Стивенс) или отлов
>сигналов? Зачем усложнять себе жизнь?
Если статус завершения дочернего процесса знать не нужно, то можно ведь просто проигнорировать sigchld, я еще не слышал нигде, чтобы кто-то жаловался, что игнорируя sgichld все равно появлялись зомби. Но да, раз Стивенс пишет waitpid как наиболее рекомендуемый(самому мне не довелось почитать), то пожалуй я соглашусь, что лучше waitpid c WHOHANG.
>Если статус завершения дочернего процесса знать не нужно, то можно ведь просто
>проигнорировать sigchld, я еще не слышал нигде, чтобы кто-то жаловался, что
>игнорируя sgichld все равно появлялись зомби.А кто сказал, что они не появятся? Сигнал генерится в любом случае, независимо от того, обрабатываем мы его или нет. Без wait зомби будет.
>А кто сказал, что они не появятся? Сигнал генерится в любом случае,
>независимо от того, обрабатываем мы его или нет. Без wait зомби
>будет.
man 3 signal сказал (на FreeBSD 5.0 и выше)
if a process explicitly specifies SIG_IGN as the action for the signal
SIGCHLD, the system will not create zombie processes when children of the
calling process exit. As a consequence, the system will discard the exit
status from the child processes. If the calling process subsequently
issues a call to wait(2) or equivalent, it will block until all of the
calling process's children terminate, and then return a value of -1 with
errno set to ECHILD.
При игнорировании sigchld, как видите, зомби не появляется. Правда только на FreeBSD >=5.0(я так понял может и не только на FreeBSD, но о других системах не в курсе). Так что согласен насчет wait.
Вообщем мне кажется вопрос закрыт, надо использовать waitpid.
По FreeBSD буду знать...
Под линукс вот наваял для уверенности, зомби остаются.void sig_func(int sig)
{
if(SIGCHLD==sig){
//fprintf(stderr,"SIGCHILD: %u\n",getpid());
}
}
int main(int argc, char **argv)
{
pid_t pid = getpid();
signal(SIGCHLD,sig_func);
for(int i=0;i<2;++i){
pid_t pd = fork();
if(!pid) break;
}
fprintf(stderr,"PARENT: %u, %u\n",pid,getpid());
if(getpid()==pid){
sleep(20);
}
return 0;
}
>signal(SIGCHLD,sig_func);
Не, не так, игнорировать надо, то бишь signal(SIGCHLD, SIG_IGN);
Кстати в мане на имеющемся у меня под рукой линуксе говорится, что не будет работать все равно, также как и на System V, и дается ссылка на posix.
>>signal(SIGCHLD,sig_func);
>Не, не так, игнорировать надо, то бишь signal(SIGCHLD, SIG_IGN);
>Кстати в мане на имеющемся у меня под рукой линуксе говорится, что
>не будет работать все равно, также как и на System V,
>и дается ссылка на posix.
Логично, что остаются зомби!! Ведь только обрабатывается сигнал,но отлов зомби не происходит =(. Надо все-таки вызвать wait* в обработчике сигнала. Это как по мне логичнее, чем время от времени проверять на зомби.
>>>signal(SIGCHLD,sig_func);
>>Не, не так, игнорировать надо, то бишь signal(SIGCHLD, SIG_IGN);
>>Кстати в мане на имеющемся у меня под рукой линуксе говорится, что
>>не будет работать все равно, также как и на System V,
>>и дается ссылка на posix.
>
>
>Логично, что остаются зомби!! Ведь только обрабатывается сигнал,но отлов зомби не происходит
>=(. Надо все-таки вызвать wait* в обработчике сигнала. Это как по
>мне логичнее, чем время от времени проверять на зомби.
К тому же - все равно логично будет сделать перебор по SIGALARM - а это опять таки сигналы =)
Перебор делается в основном цикле главного процесса, т.е.for(;;){
select(...,таймаут)
accept(...)waitpid(...)
}Кроме того, может потребоваться не только зомби закрыть, но еще и как-то обработать этот пид чилда (учавствует в логике работы программы) - в обработчике сигнала это делать нельзя, а здесь - можно.
>Логично, что остаются зомби!! Ведь только обрабатывается сигнал,но отлов зомби не происходит
>=(. Надо все-таки вызвать wait* в обработчике сигнала. Это как по
>мне логичнее, чем время от времени проверять на зомби.
А доставка сигналов негарантируется. Видимо во FreeBSD гарантируется реакция системы в, виде прибивания zombie, на sig_ign у sigchld некого процесса, потому наверное добавили такую возможность. Так или иначе не posix фича.