正常退出
1.main函数调用return
2.进程调用exit(),属于标准c库
3.进程调用_exit()或者_Exit(),属于系统调用
补充:1:进程最后一个线程返回 2:最后一个线程可以调用pthread_exit
异常退出
1.调用abort
2.当进程收到某些信号,如ctrl+c
3.最后一个线程对取消(cancellation)请求做出响应
僵尸进程
僵尸进程:是因为子进程退出状态不被收集,导致僵死僵死进程
1 #include <stdio.h>
2 #include <sys/types.h>
3 #include <unistd.h>
4 #include <stdlib.h>
5
6
7 int main()
8 {
9 pid_t pid;
10
11 int cnt =0;
12
13 pid =fork();
14 if(pid >0)
15 {
16
17 while(1){
18 printf("this is father print pid = %d\n",getpid());
19 sleep(1);
20 printf("cnt = %d\n",cnt);
21 }
22 }
23 else if(pid == 0){
24
25 while(1){
26 printf("this is son print pid = %d\n",getpid());
27 sleep(1);
28 cnt ++;
29 if(cnt == 3){
30 exit(0);
31 }
32 }
33 }
34
35 return 0;
36 }
~
从图中会发现pid为24116是僵尸进程(Z+)/zombie
为什么要等待子进程退出
是因为创建子进程的时候,不知道子进程是否完成所给的任务
如果完成任务了,有五种情况:上方所讲的正常退出
如果没有完成任务的原因是什么,有三种情况:上方所讲的异常退出
如何让父进程等待子进程退出,并收集子进程的退出状态
wait,会使调用者阻塞:如果其所有子进程都还在运行,则阻塞
waitpid 不会使调用者阻塞
如何进行检测
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
int main()
{
pid_t pid;
int cnt =0;
int status = 10;
pid =fork();
if(pid >0)
{
wait(&status);
printf("child quit child status =%d\n",WEXITSTATUS(status));
while(1)
{
printf("cnt%d \n",cnt);
printf("this is father print pid = %d\n",getpid());
sleep(1);
}
}
else if(pid == 0){
while(1){
printf("this is son print pid = %d\n",getpid());
sleep(1);
cnt ++;
if(cnt == 5){
exit(3);
}
}
}
return 0;
}
从图可以发送status读取到了子进程的exit返回值