2013-11-03 5 views
5

Im Handbuch für GNU libc über orphaned process groups immer, es erwähnte:warum SIGHUP-Signal nicht empfangen, wenn ein verwaistes Process Group

“process groups that continue running even after the session leader 
has terminated are marked as orphaned process groups. 

When a process group becomes an orphan, its processes are sent a SIGHUP 
signal. Ordinarily, this causes the processes to terminate. However, 
if a program ignores this signal or establishes a handler for it 
(see Signal Handling), it can continue running as in the orphan process 
group even after its controlling process terminates; but it still 
cannot access the terminal any more. ” 

ich ein Testprogramm schreiben, aber wenn die Prozessgruppe wird eine Waise, sein Prozess hat das SIGHUP-Signal nicht empfangen. Ich frage mich warum?

#include <errno.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <sys/types.h> 
#include <sys/wait.h> 
#include <unistd.h> 


static void 
sig_hup(int signo) //**never get called ???** 
{ 
    printf("SIGHUP received, pid = %ld\n", (long)getpid()); 
} 

static void 
pr_ids(char *name) 
{ 
    printf("%s: pid = %ld, ppid = %ld, pgrp = %ld, tpgrp = %ld\n", 
     name, (long)getpid(), (long)getppid(), (long)getpgrp(), 
     (long)tcgetpgrp(STDIN_FILENO)); 
    fflush(stdout); 
} 

int 
main(void) 
{ 
    char c; 
    pid_t pid; 

    pr_ids("parent"); 
    pid = fork(); 
    if (pid > 0) {  // parent 
     sleep(5); 
     exit(0);   // parent exit; 
    } else { 
     pr_ids("child"); 
     setsid();  //create new session, and "child" becomes the session leader 
     pid = fork(); 
     if(pid>0) { 
      sleep(20); 
      exit(0);  // "child" exit 
         // so the process group become an orphan process group 
     } 
     else{ 
      pr_ids("grandson"); 
      signal(SIGHUP, sig_hup); // establish signal handler 
      sleep(60);     // now becoming orphan process group 
      printf("end\n"); 
     } 
    } 
    exit(0); 
} 

Antwort

0

Dieses Dokument Abschnitt speziell über den Verlust eines Steueranschluss eines Prozesses spricht, das von einem Modem hangup ein in der Regel hatte, oder das virtuelle Äquivalent (eine SSH-Sitzung zu beenden, etc). (Ich denke, die Formulierung im Dokument könnte hier verbessert werden). Wenn Sie hier verwenden, geben Sie den Zugriff auf das steuernde Terminal bis zum Zeitpunkt setsid() zurück, so dass es von dort aus kein kontrollierendes Terminal mehr zu verlieren gibt.

Sie könnten open() ein TTY-Gerät (wie ein pty Slave) einen Steuerterminal zu gewinnen (beachten Sie, dass Sie als einige zusätzliche Operation kann zu tun haben, gut FreeBSD erfordert eine TIOCSCTTY ioctl), dann wieder verlieren, und dann sollten Sie das Signal SIGHUP bekommen.

1

Verwaiste Prozessgruppen erhalten SIGHUP, gefolgt von SIGCONT, wenn sie gestoppt werden, wenn sie verwaist werden.

Schlaf ist nicht genug, Sie brauchen:

kill(getpid(), SIGSTOP); 

Zusätzlich zu, dass POSIX nicht erfordert, dass SIGHUP und SIGCONT wenn die Verwaisung verursacht wurde durch setsid() oder setprgrp(), weil es nicht so war geschickt verursacht durch einen ausgehenden Prozess, der sich der Jobkontrolle nicht bewusst ist (siehe http://pubs.opengroup.org/onlinepubs/9699919799/functions/_exit.html).

Mit kill(getpid(), SIGSTOP) anstelle von sleep(60) im Kind, erhalten Sie eine gestoppte Waise mit Ihrem Programm, auch wenn Sie setsid() nicht aufrufen.

#define _GNU_SOURCE 
#include <errno.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <fcntl.h> 
#include <sys/types.h> 
#include <sys/wait.h> 
#include <unistd.h> 
#include <signal.h> 

static void 
sig_hup(int signo) //**never get called ???** 
{ 
    printf("SIGHUP received, pid = %ld\n", (long)getpid()); 
} 

static void 
pr_ids(char *name) 
{ 
    printf("%s: pid = %ld, ppid = %ld, pgrp = %ld, tpgrp = %ld\n", 
     name, (long)getpid(), (long)getppid(), (long)getpgrp(), 
     (long)tcgetpgrp(STDIN_FILENO)); 
    fflush(stdout); 
} 

int 
main(void) 
{ 
    pid_t pid; 

    pr_ids("parent"); 
    pid = fork(); 
    if (pid > 0) {  // parent 
     sleep(5); 
     _exit(0);   // parent exit; 
    } else { 
     pr_ids("child"); 

     /*setsid();  //create new session, and "child" becomes the session leader*/ 

     pid = fork(); 
     if(pid>0) { 
      sleep(2); 
      exit(0);  // "child" exit 
         // so the process group become an orphan process group 
     } 
     else{ 
      pr_ids("grandson"); 
      signal(SIGHUP, sig_hup); // establish signal handler 
      kill(getpid(), SIGSTOP); 
      printf("end\n"); 
     } 
    } 
    exit(0); 
} 

sollten Sie eine SIGHUP in das Kind bekommen, nachdem der Elternteil stirbt (5s).

Verwandte Themen