2013-11-03 15 views
5

Trong hướng dẫn cho GNU libc về orphaned process groups, nó đề cập:tại sao tín hiệu SIGHUP không nhận được khi trở thành một mồ côi Process Nhóm

“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. ” 

tôi viết một chương trình thử nghiệm, nhưng khi nhóm quá trình trở thành một đứa trẻ mồ côi, quá trình của nó không nhận được tín hiệu SIGHUP. Tôi tự hỏi tại sao?

#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); 
} 

Trả lời

0

Đó phần tài liệu được nói cụ thể về sự mất mát của một thiết bị đầu cuối kiểm soát của một quá trình mà có một thường bởi một gác modem, hoặc tương đương ảo (kết thúc một phiên ssh, vv). (Tôi nghĩ rằng các phrasing trong tài liệu có thể được cải thiện ở đây). Khi bạn sử dụng setsid() ở đây, bạn từ bỏ quyền truy cập vào thiết bị đầu cuối điều khiển khi thời gian setsid() trả về, do đó không có thiết bị đầu cuối điều khiển nào bị mất từ ​​đó về phía trước.

Bạn có thể open() một thiết bị tty (chẳng hạn như một nô lệ pty) để đạt được một thiết bị đầu cuối kiểm soát (lưu ý rằng bạn có thể phải làm một số hoạt động bổ sung cũng-FreeBSD đòi hỏi một ioctl TIOCSCTTY), sau đó đánh mất nó một lần nữa, và sau đó bạn sẽ nhận được tín hiệu SIGHUP.

1

Nhóm quá trình mồ côi nhận SIGHUP, sau đó là SIGCONT nếu chúng bị dừng khi chúng trở thành mồ côi.

Ngủ là không đủ, bạn cần:

kill(getpid(), SIGSTOP); 

Bên cạnh đó, POSIX không đòi hỏi rằng SIGHUP và SIGCONT được gửi nếu orphaning là do setsid() hoặc setprgrp() vì sau đó nó là không gây ra bởi một quá trình xuất cảnh vô tội không biết về kiểm soát công việc (xem http://pubs.opengroup.org/onlinepubs/9699919799/functions/_exit.html).

Tuy nhiên, với kill(getpid(), SIGSTOP) thay vì số sleep(60) ở trẻ em, bạn sẽ nhận được một đứa trẻ mồ côi bị dừng với chương trình của bạn ngay cả khi bạn không gọi setsid().

#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); 
} 

sẽ giúp bạn có được SIGHUP ở trẻ sau khi cha mẹ chết (5s).

Các vấn đề liên quan