LINUX.ORG.RU

Ответ на: комментарий от fortl

извиняюсь опечатка следует читать "как уведомить потомка о смерти родителя или почему при убиении родителя потомки не получают SIGHUP как написано в мане???"

>это в каком мане так написано????????

man 7 signal

а также в некоторых книгах

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

sighup и sigchld - разные вещи

а в man 7 signal написано не про отправку сигнала, когда умирает родитель! сигнал посылается, когда умирает управляющий процесс

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

Ок, что такое "управляющий процесс" ибо некоторые бумажные руководства истолковывают его как родителя

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

почитал стивенса и возникли следующие вопросы:

"управляющий процесс" это session leader или "session leader с управляющим терминалом"????

мой парент - это session leader но без управляющего терминала. если исходить из того что sighup нерассылаются - значит он не "управляющий процесс"???

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

Из man 2 setpgid:

If the session leader exits, the SIGHUP signal will be sent to each process in the foreground process group of the controlling terminal.

То есть не только управляюший tty лидеру надо, но и процессы должны быть foreground.

Die-Hard ★★★★★
()

не уверен, что это именно то, что вам нужно, но в linux
есть возможность указать сигнал, который будет послан
потомкам завершившегося процесса:

        prctl(PR_SET_PDEATHSIG, SIGXXX);

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

спасибо, мне это поможет

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

> попробовал. что-то никакие сигналы потомкам не приходят. ядро со slackware 10.0

У меня работает, SUSE 9.2 (2.6.8-24.11-default)
Ты в какой момент prctl вызываешь? IMHO надо вызывать _после_ fork()
в child процессе.

$ man prctl
...
PR_SET_PDEATHSIG
This value is cleared upon a fork().
...

То есть это потомок должен явно сказать "хочу получить сигнал",
родитель не может сказать "пошлите сигнал потомку после моего
завершения".

HTH

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

>То есть это потомок должен явно сказать "хочу получить сигнал", родитель не может сказать "пошлите сигнал потомку после моего завершения".

понятно а я то всё наоборот понял ;-)

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

> А ещё траблу обнаружил: я не могу этот сигнал перехватить и обработать.

Ну... не знаю... вроде работает:

$ cat sigp.c
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/prctl.h>
#include <sys/types.h>
  
void die(const char* msg) { perror(msg); exit(1); }
 
void sig_handler(int sig)
{
   printf("Caught signal %d\n", sig);
}
  
int main(void)
{
   sigset_t sset;
   pid_t child = fork();
   if (child == -1) die("fork");
   if (child)
   {
       printf("Parent going to spleep\n");
       sleep(5);
       printf("Parent going to exit\n");
   }
   else
   {
       if (signal(SIGUSR1, sig_handler) == SIG_ERR)  die("signal");
       if (prctl(PR_SET_PDEATHSIG, SIGUSR1) == -1)   die("prctl");
       printf("Child waiting for signal\n");
       sigemptyset(&sset);
       sigsuspend(&sset);
       printf("Child exiting\n");
   }
}
 
$ make sigp
cc     sigp.c   -o sigp
$ ./sigp
Child waiting for signal
Parent going to spleep
Parent going to exit
Caught signal 10
Child exiting
$

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

а у меня почти тоже самое не работает. только я запрашиваю SIGHUP а не юзр1

тоесть потомок завершает свою работу без каких либо сообщений

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

                switch(rules_arr[i]->pid=fork()){                                                                              
                    case -1:syslog(LOG_ERR, "MONITOR:Can't fork worker (%m) - aborted");exit(1);break;/* failed to spawn son */
                    case  0://дочерний процесс                                                                                 
                            prctl(PR_SET_PDEATHSIG, SIGHUP);//просим присылать SIGHUP при неожиданном умирании MONITOR-a       
                            catch_signals_child();                                                                             
                            execute_worker(rules_arr[i]);                                                                      
                            exit(0);break;                                                                                     
                    default:close(rules_arr[i]->socket);                                                                       
                            syslog(LOG_INFO,"MONITOR:start worker with pid=%d SUCCESS",rules_arr[i]->pid);                     
                }                                                                                                              

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

void catch_signals_child(void){                                                                                                
    struct sigaction sa_new={};                                                                                                
    unsigned i;                                                                                                                
                                                                                                                               
    int siglist_terminate[] = { SIGHUP, SIGTERM };                                                                             
    int siglist_ignore[]    = { SIGINT, SIGQUIT, SIGPIPE, SIGCHLD };                                                           
                                                                                                                               
    sa_new.sa_handler = sighandler_terminate;                                                                                  
    sigemptyset(&sa_new.sa_mask);                                                                                              
                                                                                                                               
    for (i = 0; i < G_N_ELEMENTS(siglist_terminate); ++i)   sigaction(siglist_terminate[i], &sa_new, NULL);                    
                                                                                                                               
    //sa_new.sa_handler = SIG_IGN;                                                                                             
    sa_new.sa_handler = sighandler_ignore;                                                                                     
    sa_new.sa_flags   = SA_RESTART;                                                                                            
    for (i = 0; i < G_N_ELEMENTS(siglist_ignore);    ++i)   sigaction(siglist_ignore[i],    &sa_new, NULL);                    
} 

static void sighandler_terminate(int signo) {                                                                                  
    if(signo!=SIGHUP)syslog(LOG_INFO,"signal #%d (%s) catched, exiting",    signo, strsignal(signo));                          
    else syslog(LOG_ERR,"ERROR:signal #%d (%s) catched:Unexpected death of MONITOR. Aborting",    signo, strsignal(signo));    
    g.agent_cont=false;                                                                                                        
}                                                                                                                              
static void sighandler_sigchild (int signo)                                                                                    
        { syslog(LOG_INFO,"signal #%d (%s) catched, restart child",    signo, strsignal(signo)); g.child_exited=true;}         
static void sighandler_ignore   (int signo)                                                                                    
        { syslog(LOG_INFO,"signal #%d (%s) catched and ignored", signo, strsignal(signo));}                                    

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


Черт его знает... попробовал с sigaction() - тоже работает.
А если ты этому процессу-потомку руками (kill) посылаешь
сигнал - он его ловит?
Может попробуй запустить мой примерчик, чтобы уж наверняка
исключить возможные глюки твоей (большой) программы.

P.S. Я бы все равно этот prctl() не использовал - во-первых
непортабельно, во-вторых - разве он настолько необходим?

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

>А если ты этому процессу-потомку руками (kill) посылаешь сигнал - он его ловит?

да, без проблем

>P.S. Я бы все равно этот prctl() не использовал - во-первых непортабельно, во-вторых - разве он настолько необходим?

один из немногих способов не оставить в системе массу работающих но неуправляемых процессов

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

> > P.S. Я бы все равно этот prctl() не использовал - во-первых непортабельно, во-вторых - разве он настолько необходим?

> один из немногих способов не оставить в системе массу работающих но неуправляемых процессов

Странно... есть куча Unix-программ, которые так или иначе используют
сопроцессы. Да взять хоть бы apache. Или (AFAIK) oracle. Или sendmail.
И еще вагон и тележка. И живут они без prctl, и не оставляют "массу
работающих но неуправляемых процессов".

Может чо-то в дизайне надо подправить?

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

>Может чо-то в дизайне надо подправить?

навряд

идея простая: есть некоторый монитор(типа opmn in oracle) который следит за дочерними процессами решающими основную задачу. так вот я хочу дабы при непроизвольном исчезновении монитора все запущенные им процессы сами свернулись. в оракле такое не реализовано.

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

> идея простая: есть некоторый монитор(типа opmn in oracle) который
> следит за дочерними процессами решающими основную задачу. так вот я
> хочу дабы при непроизвольном исчезновении монитора все запущенные им
> процессы сами свернулись. в оракле такое не реализовано.
>

Ну ты подумай сам - что значит "непроизвольное исчезновение монитора"?
Это значит, что у тебя _баг_, раз он "непроизвольно" исчез. Причем
это очень исключительный, грубый баг - типа SIGSEGV или почему-то
SIGKILL. Обрабатывать эту ситуацию это примерно то же самое, что
перехватывать SIGSEGV и пытаться делать recovery.

Да, и не надо говорить - "вдруг админ сделает мой программе kill -9".
Ну, сделает. Не твое дело. Если админ это делает, он очевидно отдает
себе отчет и знает семантику SIGKILL.

Если же у тебя задача _перезапуска_ сдохшего (по каким-то причинам)
процесса, то это дело шелл-скрипта из пары строчек:
killall ...
<программа>
Все это дело завернуть в цикл (ну или прописать в inittab).

Альтернативно вместо killall можно встроить "зачистку" остатков
прямо к себе в программу.

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

> а если мою программу прибьёт oom-killer???

И что? Это вне твоего контроля. Если у твоей программы действительно
какие-то особые, большие потребности в памяти, запиши это в INSTALL
или куда там еще. У тебя же все равно где-то описаны "System
Requirements" для твоей программы, ведь правда? ;-)
Там же ты можешь дать админу/пользователю инструкции по отключению
oom-killer или просто предупредить, что памяти надо столько-то.

Можешь еще при запуске посмотреть в /proc/где-это-там и если там стоит
стратегия с oom-killer записать warning в лог.

Это нормально. Например программы, активно использующие SysV IPC
(который регулируется system-wide ограничениями) в описание
инсталляции включают требования по настройке SysV IPC (AFAIK то же
oracle). Не надо делать из админа/пользователя дебила, неспособного
прочитать документацию.

HTH

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

более подробное изучение показало что поведение потомка зависит от того какой смертью умирает parent. тоесть при kill -9 потомки умирают так как я описал выше а при убиении SIGINT всё происходит как ожидалось

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

Ну у меня и при SIGKILL потомок получает сигнал. Только это ничего
не значит. Нестандартный, непереносимый хак. И в общем-то ненужный.
IMHO.

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

> более подробное изучение показало что поведение потомка
> зависит от того какой смертью умирает parent.

да быть того не может. ну, разве что, вас нашел kernel
bug, в чем я сильно сомневаюсь :)

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