防止子进程变成僵尸进程

    1. #include <stdio.h>
    2. #include <stdlib.h> //malloc,exit
    3. #include <unistd.h> //fork
    4. #include <signal.h>
    5. #include <sys/wait.h> //waitpid
    6. //信号处理函数
    7. void sig_usr(int signo)
    8. {
    9. int status;
    10. switch(signo)
    11. {
    12. case SIGUSR1:
    13. printf("收到了SIGUSR1信号,进程id=%d!\n",getpid());
    14. break;
    15. case SIGCHLD:
    16. printf("收到了SIGCHLD信号,进程id=%d!\n",getpid());
    17. //这里大家学了一个新函数waitpid,有人也用wait,但老师要求大家掌握和使用waitpid即可;
    18. //这个waitpid说白了获取子进程的终止状态,这样,子进程就不会成为僵尸进程了;
    19. pid_t pid = waitpid(-1,&status,WNOHANG); //第一个参数为-1,表示等待任何子进程,
    20. //第二个参数:保存子进程的状态信息(大家如果想详细了解,可以百度一下)。
    21. //第三个参数:提供额外选项,WNOHANG表示不要阻塞,让这个waitpid()立即返回
    22. if(pid == 0) //子进程没结束,会立即返回这个数字,但这里应该不是这个数字
    23. return;
    24. if(pid == -1) //这表示这个waitpid调用有错误,有错误也理解返回出去,我们管不了这么多
    25. return;
    26. //走到这里,表示 成功,那也return吧
    27. return;
    28. break;
    29. } //end switch
    30. }
    31. int main(int argc, char *const *argv)
    32. {
    33. pid_t pid;
    34. printf("进程开始执行!\n");
    35. //先简单处理一个信号
    36. if(signal(SIGUSR1,sig_usr) == SIG_ERR) //系统函数,参数1:是个信号,参数2:是个函数指针,代表一个针对该信号的捕捉处理函数
    37. {
    38. printf("无法捕捉SIGUSR1信号!\n");
    39. exit(1);
    40. }
    41. if(signal(SIGCHLD,sig_usr) == SIG_ERR)
    42. {
    43. printf("无法捕捉SIGCHLD信号!\n");
    44. exit(1);
    45. }
    46. //---------------------------------
    47. pid = fork(); //创建一个子进程
    48. //要判断子进程是否创建成功
    49. if(pid < 0)
    50. {
    51. printf("子进程创建失败,很遗憾!\n");
    52. exit(1);
    53. }
    54. //现在,父进程和子进程同时开始 运行了
    55. for(;;)
    56. {
    57. sleep(1); //休息1秒
    58. printf("休息1秒,进程id=%d!\n",getpid());
    59. }
    60. printf("再见了!\n");
    61. return 0;
    62. }