关于SIGHCLD和SIGCLD

SIGCLD

简单的说, SIGCLD不是可靠信号. 这里的不可靠是指当大量信号来的时候, 重复信号它只会处理一次, 而不是多次. 很多信号在瞬间("同时")产生,内核也不一定能够一一处理, 不保证产生的次数.


SIGHCLD

  • 如果父进程在fork之后调用wait,就会阻塞,直到有一个子进程退出。如果父进程在fork之前先signal(SIGCLD,Fun),即注册了SIGCLD的信号处理函数。然后做自己的事情。
    当子进程退出时,会给父进程发送一个SIGCLD信号。然后Fun函数就会执行。可以在Fun函数中调用wait获得子进程退出时的状态,并且此时wait不会阻塞。
    当Fun函数执行完后,父进程又继续做自己的事情。

  • SIGCHLD简单的说,子进程退出时父进程会收到一个SIGCHLD信号,默认的处理是忽略这个信号,而常规的做法是在这个信号处理函数中调用wait函数获取子进程的退出状态。

  
  
  1. /*************************************************************************
  2. > File Name: SIGCHLD_SIGCLD.cpp
  3. > Author: Function_Dou
  4. > Mail:
  5. > Created Time: 2018年02月03日 星期六 17时56分10秒
  6. ************************************************************************/
  7. #include<sys/wait.h>
  8. #include<stdio.h>
  9. #include<stdlib.h>
  10. #include<unistd.h>
  11. #include<sys/wait.h>
  12. static void sig_cld(int);
  13. int main()
  14. {
  15. pid_t pid;
  16. // if(signal(SIGCLD,sig_cld) == SIG_ERR)
  17. if(signal(SIGCHLD,sig_cld) == SIG_ERR)
  18. {
  19. printf("signal error\n");
  20. exit(-1);
  21. }
  22. if((pid = fork()) < 0)
  23. {
  24. printf("fork error\n");
  25. exit(-1);
  26. }
  27. else if(pid == 0)
  28. {
  29. //child
  30. printf("%d fork a new child %d\n",getppid(),getpid());
  31. sleep(1);
  32. exit(0);
  33. }
  34. else
  35. {
  36. //parent
  37. // sig_cld(0);
  38. int i,j;
  39. for(i=0;i<100;i++)
  40. {
  41. for(j=0;j<10000000;j++)
  42. ;
  43. printf("%d\n",i);
  44. }
  45. }
  46. }
  47. static void sig_cld(int)
  48. {
  49. pid_t pid;
  50. int status;
  51. printf("SIGCLD received\n");
  52. // wait() 返回退出状态
  53. if((pid = wait(&status)) <0)
  54. {
  55. printf("wait error\n");
  56. }
  57. printf("pid = %d\n",pid);
  58. }

运行结果

  
  
  1. [root@localhost Signal]# ./a.out
  2. 13936 fork a new child 13937
  3. 0
  4. 1
  5. 2
  6. ...
  7. 51
  8. 52
  9. SIGCLD received
  10. pid = 13937
  11. 53
  12. 54
  13. ...

从运行就可以看出来, 信号中的函数调用wait()父进程依然在运行, 当子进程结束后, 父进程接着执行.
当去掉signal那段函数, 在else中调用sig_cld()函数, 结果将发生改变, 当子进程结束, 父进程才继续运行.

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值