前台进程组多个进程同时接收终端信号的测试

来源:互联网 发布:网络控制手机发短信 编辑:程序博客网 时间:2024/06/01 23:25

在unix高级编程的信号一章中,有个例子,讲到前台进程组多个进程同时接收终端信号。

为了能够深入理解这个问题,以及exec后父进程的信号捕获被子进程恢复为默认的情况,设计了一个小的程序来测试。

#include "apue.h"
  2 #include <time.h>
  3
  4 static void
  5 sig_int(int signo)
  6 {
  7     printf("caught SIGINT\n");
  8     if (signal(SIGINT, sig_int) == SIG_ERR)
  9         err_sys("signal(SIGINT) error");
 10 }
 11
 12 static void
 13 sig_chld(int signo)
 14 {
 15     printf("caught SIGCHLD\n");
 16 }
 17
 18 int
 19 main(void)
 20 {
 21     pid_t pid;
 22     int status;
 23     time_t starttime;
 24
 25     if (signal(SIGINT, sig_int) == SIG_ERR)
 26         err_sys("signal(SIGINT) error");
 27     if (signal(SIGCHLD, sig_chld) == SIG_ERR)
 28         err_sys("signal(SIGCHLD) error");
 29     if (pid = fork() < 0)
 30     {
 31         status = -1;
 32     }
 33     else if (pid == 0)
 34     {   starttime = time(NULL);
 35         for (;;)
 36             if (time(NULL) > starttime + 60)
 37                 break;
 38     }
 39
 40     starttime = time(NULL);
 41         for (;;)
 42             if (time(NULL) > starttime + 65)
 43                 break;
 44
 45     exit(0);
 46 }

此时,两个进程都等待超时。在终端键入ctrl+c,如下:

ThinkCentre:~/unixcode$ a.out
^Ccaught SIGINT
caught SIGINT
^Ccaught SIGINT
caught SIGINT
^Ccaught SIGINT
caught SIGINT
^Ccaught SIGINT
caught SIGINT
^Ccaught SIGINT
caught SIGINT
^Ccaught SIGINT
caught SIGINT
^Ccaught SIGINT
caught SIGINT
^Ccaught SIGINT
caught SIGINT
^Ccaught SIGINT
caught SIGINT
caught SIGCHLD

ctrl+c无法使得进程退出,子进程继承了父亲进程对信号的捕获,每次按ctrl c,都会产生两条打印信息。

最后两个进程都超时,父亲进程收到子进程发出的child信号结束。

接下来,将程序进行了修改,子进程exec一个程序,该程序只是等待60秒超时,不过不会捕获任何信号。

  1 #include "apue.h"
  2 #include <time.h>
  3
  4 static void
  5 sig_int(int signo)
  6 {
  7     printf("caught SIGINT\n");
  8     if (signal(SIGINT, sig_int) == SIG_ERR)
  9         err_sys("signal(SIGINT) error");
 10 }
 11
 12 static void
 13 sig_chld(int signo)
 14 {
 15     printf("caught SIGCHLD\n");
 16 }
 17
 18 int
 19 main(void)
 20 {
 21     pid_t pid;
 22     int status;
 23     time_t starttime;
 24
 25     if (signal(SIGINT, sig_int) == SIG_ERR)
 26         err_sys("signal(SIGINT) error");
 27     if (signal(SIGCHLD, sig_chld) == SIG_ERR)
 28         err_sys("signal(SIGCHLD) error");
 29     if ((pid = fork()) < 0)
 30     {
 31         status = -1;
 32     }
 33     else if (pid == 0)
 34     {
 35         if (execl("/home/liyifeng/unixcode/sigtest2", "sigtest2", (char *)0) <0)
 36             err_sys("exec  error");

 37     }
 38
 39     printf("in sigtest1\n");
 40     starttime = time(NULL);
 41         for (;;)
 42             if (time(NULL) > starttime + 65)
 43                 break;
 44
 45     exit(0);
 46 }

执行情况如下:

liyifeng@liyifeng-ThinkCentre:~/unixcode$ a.out
in sigtest1
in sigtest2
^Ccaught SIGCHLD
caught SIGINT
^Ccaught SIGINT
^Ccaught SIGINT
^Ccaught SIGINT
^Ccaught SIGINT
^Ccaught SIGINT
^Ccaught SIGINT
^Ccaught SIGINT
^Ccaught SIGINT

可见,键入第一个ctrl + c后,父亲进程收到了SIGCHLD信号,表明子进程没有继承父亲进程的捕获配置,此时子进程被ctrl c中断退出,父亲进程继续运行,直到超时结束。


小结:

子进程未exec时,继承了父亲进程的信号捕获配置,而exec后,则将父亲进程的信号捕获配置恢复为默认。

0 0
原创粉丝点击