Chinaunix首页 | 论坛 | 博客
  • 博客访问: 529532
  • 博文数量: 142
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 1452
  • 用 户 组: 普通用户
  • 注册时间: 2013-09-12 16:28
文章分类

全部博文(142)

文章存档

2016年(10)

2015年(60)

2014年(72)

我的朋友

分类: C/C++

2014-09-17 11:24:18

子进程会继承父进程的信号处理函数。
当一个进程fork一个子进程时,子进程会继承父进程的存储映射,所以捕捉函数的地址在子进程中是有意义的,所以子进程会继承父进程的信号处理函数。特殊的是exec,因为exec运行新的程序后会覆盖从父进程继承来的存储映像,那么信号捕捉函数在新程序中已无意义,所以exec会将原先设置为要捕捉的信号都更改为默认动作。


点击(此处)折叠或打开

  1. #include <unistd.h>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <signal.h>
  5. static void sig_exit()
  6. {
  7.     printf("sig exit pid=%d,ppid=%d\n",getpid(),getppid());
  8. }

  9. static void sig_alrm()
  10. {
  11.     printf("sig alrm pid=%d,ppid=%d\n",getpid(),getppid());
  12. }
  13. static void sig_int()
  14. {
  15.     printf("sig int pid=%d,ppid=%d\n",getpid(),getppid());
  16. }

  17. int main()
  18. {
  19.     pid_t pid;
  20.     int status;
  21.     int sleep_time=0;
  22.     struct sigaction act,old_act;
  23.     
  24.     sigemptyset(&act.sa_mask);
  25.     act.sa_flags=0;
  26.     act.sa_handler=sig_exit;
  27.     sigaction(SIGUSR1,&act,&old_act);
  28.     

  29.     act.sa_handler=sig_alrm;
  30.     act.sa_flags=0;
  31.     sigemptyset(&act.sa_mask);
  32.     sigaction(SIGALRM,&act,&old_act);

  33.     sigemptyset(&act.sa_mask);
  34.     act.sa_flags=0;
  35.     act.sa_handler=sig_int;
  36.     sigaction(SIGINT,&act,&old_act);

  37.     if((pid=fork()) <0)
  38.         printf("fork() error\n");
  39.     else if(pid == 0) {
  40.         printf("pid in chlid =%d\n",getpid());
  41.         kill(getpid(),SIGUSR1);
  42.         alarm(2);
  43.         printf("----------\n");
  44.         sleep_time=sleep(20);
  45.         printf("+++++sleep_time=%d+++++++\n",sleep_time);
  46.         exit(0);
  47.     }
  48.     wait(&status);

  49.     printf("parent id =%d,status=[%d]\n",getpid(),status);

  50.     return 0;
  51. }
编译运行:
gwwu@hz-dev2.wgw.com:~/test/process>gcc -g signal.c -o a
gwwu@hz-dev2.wgw.com:~/test/process>./a
pid in chlid =6617
sig exit pid=6617,ppid=6616
----------
sig alrm pid=6617,ppid=6616
+++++sleep_time=18+++++++            ////sleep的返回被alarm(2)中断.并且可以知道alarm和sleep交互存在的时候,如果alarm的时间小于sleep的时间,alarm仍然有效。
parent id =6616,status=[0]
gwwu@hz-dev2.aerohive.com:~/test/process>

可见父进程中的信号处理函数在子进程中是有效的,当然子进程也可以定义自己的信号处理函数。

点击(此处)折叠或打开

  1. #include <unistd.h>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <signal.h>
  5. static void sig_exit()
  6. {
  7.     printf("sig exit pid=%d,ppid=%d\n",getpid(),getppid());
  8. }

  9. static void sig_alrm()
  10. {
  11.     printf("sig alrm pid=%d,ppid=%d\n",getpid(),getppid());
  12. }
  13. static void sig_int()
  14. {
  15.     printf("sig int pid=%d,ppid=%d\n",getpid(),getppid());
  16. }
  17. static void sig_child_exit()
  18. {
  19.     printf("sig child exit pid=%d,ppid=%d\n",getpid(),getppid());
  20. }

  21. int main()
  22. {
  23.     pid_t pid;
  24.     int status;
  25.     int sleep_time=0;
  26.     struct sigaction act,old_act;
  27.     
  28.     sigemptyset(&act.sa_mask);
  29.     act.sa_flags=0;
  30.     act.sa_handler=sig_exit;
  31.     sigaction(SIGUSR1,&act,&old_act);
  32.     

  33.     act.sa_handler=sig_alrm;
  34.     act.sa_flags=0;
  35.     sigemptyset(&act.sa_mask);
  36.     sigaction(SIGALRM,&act,&old_act);

  37.     sigemptyset(&act.sa_mask);
  38.     act.sa_flags=0;
  39.     act.sa_handler=sig_int;
  40.     sigaction(SIGINT,&act,&old_act);

  41.     if((pid=fork()) <0)
  42.         printf("fork() error\n");
  43.     else if(pid == 0) {
  44.         printf("pid in chlid =%d\n",getpid());
  45.         sigemptyset(&act.sa_mask);
  46.         act.sa_flags=0;
  47.         act.sa_handler=sig_child_exit;
  48.         sigaction(SIGUSR1,&act,&old_act);
  49.         kill(getpid(),SIGUSR1);
  50.         alarm(2);
  51.         printf("----------\n");
  52.         sleep_time=sleep(20);
  53.         printf("+++++sleep_time=%d+++++++\n",sleep_time);
  54.         exit(0);
  55.     }
  56.     wait(&status);

  57.     printf("parent id =%d,status=[%d]\n",getpid(),status);

  58.     return 0;
  59. }
编译运行:
gwwu@hz-dev2.wgw.com:~/test/process>gcc -g signal.c -o a
gwwu@hz-dev2.wgw.com:~/test/process>./a
pid in chlid =6675
sig child exit pid=6675,ppid=6674            ///子进程运行了自己定义的信号处理函数,覆盖了父进程的信号处理函数
----------
sig alrm pid=6675,ppid=6674
+++++sleep_time=18+++++++
parent id =6674,status=[0]


另外如果是外部进程传入的信号,父子进程同时相应。

点击(此处)折叠或打开

  1. #include <unistd.h>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <signal.h>
  5. static void sig_exit()
  6. {
  7.     printf("sig exit pid=%d,ppid=%d\n",getpid(),getppid());
  8. }

  9. static void sig_alrm()
  10. {
  11.     printf("sig alrm pid=%d,ppid=%d\n",getpid(),getppid());
  12. }
  13. static void sig_int()
  14. {
  15.     printf("sig int pid=%d,ppid=%d\n",getpid(),getppid());
  16. }
  17. static void sig_child_exit()
  18. {
  19.     printf("sig child exit pid=%d,ppid=%d\n",getpid(),getppid());
  20. }

  21. int main()
  22. {
  23.     pid_t pid;
  24.     int status;
  25.     int sleep_time=0;
  26.     struct sigaction act,old_act;
  27.     
  28.     sigemptyset(&act.sa_mask);
  29.     act.sa_flags=0;
  30.     act.sa_handler=sig_exit;
  31.     sigaction(SIGUSR1,&act,&old_act);
  32.     

  33.     act.sa_handler=sig_alrm;
  34.     act.sa_flags=0;
  35.     sigemptyset(&act.sa_mask);
  36.     sigaction(SIGALRM,&act,&old_act);

  37.     sigemptyset(&act.sa_mask);
  38.     act.sa_flags=0;
  39.     act.sa_handler=sig_int;
  40.     sigaction(SIGINT,&act,&old_act);

  41.     if((pid=fork()) <0)
  42.         printf("fork() error\n");
  43.     else if(pid == 0) {
  44.         printf("pid in chlid =%d\n",getpid());
  45.         sigemptyset(&act.sa_mask);
  46.         act.sa_flags=0;
  47.         act.sa_handler=sig_child_exit;
  48.         sigaction(SIGUSR1,&act,&old_act);
  49.         kill(getpid(),SIGUSR1);
  50.         alarm(10);
  51.         printf("----------\n");
  52.         sleep_time=sleep(2);
  53.         printf("+++++sleep_time=%d+++++++\n",sleep_time);
  54.         exit(0);
  55.     }
  56.     wait(&status);

  57.     printf("parent id =%d,status=[%d]\n",getpid(),status);

  58.     return 0;
  59. }

编译运行:
gwwu@hz-dev2.wgw.com:~/test/process>./a
pid in chlid =6695
sig child exit pid=6695,ppid=6694
----------
^Csig int pid=6695,ppid=6694            ////Ctrl+C 中断, 发现父子进程都会对SIGINT信号进行处理
+++++sleep_time=1+++++++
sig int pid=6694,ppid=32689
parent id =6694,status=[0]


阅读(976) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~