- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <unistd.h>
- #include <sys/types.h>
- #include <sys/wait.h>
- #include <signal.h>
-
- //父进程循环创建三个子进程, 并用sigchld完成对子进程的回收
- /*
- 1. fork 循环3次 if()
- 2. 在父进程中注册信号处理函数,在子进程中睡眠,然后不同时间段退出
- 3. 设置未决信号集 , 阻塞信号集 , 将sigchld添加到阻塞信号集合中, 在完成信号注册后,解除对sigchld信号的阻塞. 这一步的目的是 : 为了防止父进程还没有完成对sigchld信号的注册, 子进程就结束了, 没有利用到sigchld回收子进程, 子进程就变成了僵尸进程
- sigset_t mask;
- sigemptyset(&mask);
- sigaddset(&mask , SIGCHLD);
- sigprocmask(SIG_BLOCK , &mask , NULL);
-
- //注册
- sigprocmask(SIG_UNBLOCK , &mask , NULL);
- 4. 注册信号处理函数的过程: 利用sigaction(SIGCHLD , )
- struct sigaction act;
- act.sa_handler = chld;
- sigemptyset(&act.sa_mask); //清空信号集中的信号
- act.sa_flags = 0;
- sigaction(SIGINT , &act , NULL);
-
- */
-
- void chld(int signo)
- {
- pid_t wpid;
- while(1)
- {
- wpid = waitpid(-1 , NULL , WNOHANG);
- if(wpid == 0 && wpid < 0) //子进程还活着 没子进程活着了
- {
- break;
- }else if(wpid>0) //子进程退出 返回子进程pid
- {
- printf("exit . child sig = [%d]\n" , wpid);
- }
- }
- }
-
-
- int main()
- {
- int i;
- sigset_t mask;
- sigemptyset(&mask);
- sigaddset(&mask ,SIGCHLD);
- sigprocmask(SIG_BLOCK , &mask , NULL);
-
- for(i=0; i<3; i++)
- {
- int pid = fork();
- if(pid < 0)
- {
- perror("fork error");
- }
- else if(pid > 0)
- {
- printf("father pid=[%d]\n", getpid());
- }
- else
- {
- printf("son pid = [%d]\n",getpid());
- break; //1. err1 这里应该break ,防止子进程创建子进程
- }
- }
- if(i==0)
- {
- printf("i==[%d], son pid = [%d]\n",i, getpid());
- sleep(1);
- }
- if(i==1)
- {
- printf("i==[%d], son pid = [%d]\n",i, getpid());
- sleep(2);
- }
- if(i==2)
- {
- printf("i==[%d], son pid = [%d]\n",i, getpid());
- sleep(1);
- }
- else if(i==3)
- {
- struct sigaction act;
- act.sa_handler = chld;
- sigemptyset(&act.sa_mask);
- act.sa_flags = 0;
- //这里加延时 是为了模拟: 父进程还没来得及注册信号处理函数 , 子进程就全部退出了的情形!
- sigaction(SIGCHLD , &act , NULL);
-
- sigprocmask(SIG_UNBLOCK , &mask ,NULL);
- while(1)
- {
- sleep(1); //sleep(1) 是为了防止空转速度过快
- }
- }
- return 0;
- }
holo@holo:~/fwq$ ./sigchld
father pid=[33860]
son pid = [33861]
i==[0], son pid = [33861]
father pid=[33860]
son pid = [33862]
i==[1], son pid = [33862]
father pid=[33860]
son pid = [33863]
i==[2], son pid = [33863]
exit . child sig = [33861]
exit . child sig = [33863]
exit . child sig = [33862]^C