一、子进程退出时会给父进程发送信号
默认的父进程对子进程的操作是忽略,而子进程退出时会向父进程发送一个信号,我们现在要做的就是捕捉子进程退出时向父进程发送的信号。
代码如下:
1 #include <stdio.h>
2 #include <unistd.h>
3 #include <signal.h>
4 #include <sys/wait.h>
5 #include <stdlib.h>
6 #include <sys/types.h>
7
8 void catchSig(int sig)
9 {
10 printf("get a sig : %d, pid : %d\n",sig, getpid());
11 }
12
13 int main()
14 {
15 signal(SIGCHLD,catchSig);
16 pid_t id = fork();
17 if(id == 0)
18 {
19 printf("I am child,quit!,pid = %d\n",getpid());
20 exit(1);
21 }
22 else
23 {
24 waitpid(id, NULL, 0);
25 }
26 return 0;
27 }
执行结果:
由图,前一个pid为子进程当时的pid,后一个pid为父进程的pid,子进程发送信息并退出,父进程接受子进程发送的信号,并捕捉信号,显示出来。
二、父进程等待子进程的异步方式
父进程自定义处理函数,采用非阻塞方式等待,当子进程退出时,向父进程发送信号,父进程进行回收,并反馈信息。
代码如下:
1 #include <stdio.h>
2 #include <unistd.h>
3 #include <signal.h>
4 #include <sys/wait.h>
5 #include <stdlib.h>
6 #include <sys/types.h>
7
8 void catchSig(int sig)
9 {
10 do{
11 pid_t ret = waitpid(-1, NULL, WNOHANG);
12 if(ret > 0)
13 {
14 printf("wait sucess: %d\n ",ret);
15 }
16 else
17 {
18 printf("wait failed\n");
19 break;
20 }
21 }while(1);
22 }
23
24 int main()
25 {
26 signal(SIGCHLD,catchSig);
27 pid_t id = fork();
28 if(id == 0)
29 {
30 printf("I am child,quit!,pid = %d\n",getpid());
31 sleep(4);
32 exit(1);
33 }
34 else
35 {
36 while(1)
37 {
38 printf("do father things!\n");
39 sleep(1);
40 }
41 }
42 return 0;
43 }
执行结果:
首先父进程做自己的工作,输出do things,接着子进程退出并发送信号,父进程接着做自己的事情,四秒之后,等待成功,但由于只执行一次,所以后一次等待失败,父进程依旧做自己的事情。到此程序结束,验证完成。