进程控制有关结束
一般来说进程退出有三种场景:
1.代码跑完了,正常退出
2.代码跑完了,结果不对
3.代码直接异常终止了
当我们的代码出现异常,在我们vs里面出现的场景就是程序崩溃了,这时退出码也就没有了意义。
那么我们应该怎样查询最近一次进程退出时的代码呢?在shall里面用echo $?
main函数的return值时进程的退出码,那么退出码用来干嘛呢?答:退出码用来判断结果是否正确用的
返回0:默认success,出现其他的不同返回值对应不同的程序错误,毕竟错误的原因有很多,!0:fail
1.我们对main()函数的return,表示进程退出
2.非main函数return值,表示函数的返回值
exit
exit可以在任意地方直接调用,都表示终止进程,exit(a),这个a代表的就是退出码。
不管时exit还是直接main return本身都会要求系统刷新缓冲区,
_exit表示直接终止程序,是强行终止进程,不会进行后续的收尾工作,比如刷新缓冲区。
那么在进程退出时,OS层面会做什么呢?
当OS层面少了一个进程:会free掉PCB,free mm_struct,free 页表,代码+数据也会全部回收,申请的空间也会否掉。
二、wait,waitpid
我们知道fork():子进程:是为了帮助父进程完成某种任务用的,如果子进程没结束,父进程先结束了,子进程就会成为孤儿进程就被OS领养;如果子进程已经结束了,而父进程在死循环,子进程就会出现僵尸进程,那么为了避免出现子进程都成僵尸了没人理,我们的父进程在fork之后就需要wait/waitpid进行等待子进程完成它的使命。
那么为什么要让父进程等待呢?
1.通过获得子进程退出的信息,能得知子进程执行的结果。
2.可以保证:时序问题,子进程先退出,父进程后退出,父进程必须得等子进程完成之后才能结束
3.进程退出时会先进入僵尸状态,会造成内存泄漏的问题,需要通过父进程的wait来该子进程占用的资源。
1 #include <stdio.h>
2 #include<string.h>
3 #include<stdlib.h>
4 #include<unistd.h>
5 #include <sys/types.h>
6 #include<sys/wait.h>
7
8 int main()
9 {
10 pid_t id=fork();
11 if(id<0)
12 {
13 perror("fork");
14 exit(1);//进程运行完毕,结果不正确
15 }
16 else if(id==0)
17 {
18 //子进程
19 int cnt=5;
20 while(cnt)
21 {
22 // int*p=NULL;
23 // *p=100;
24 printf("cnt: %d,我是子进程,pid: %d,ppid:%d\n",cnt,getpid(),getppid());
25 sleep(1);
26 cnt--;
27 }
28 exit(202);//终止了子进程
29 }
30 else{
31 //父进程
32 printf("我是父进程,pid:%d,ppid:%d\n",getpid(),getppid());
33 // pid_t ret=wait(NULL);//父进程在阻塞式的等待
34 int status=0;
35 pid_t ret=waitpid(id,&status,0);//等价于wait
36 if(ret>0)
37 {
38 printf("等待子进程成功,ret:%d,子进程收到的信号编码:%d,子进程退出码status:%d\n",ret,status&0x7F,(status>>8)&0xFF);
39 }
40 }
41 }
可以看到,这里确实父进程得到了子进程的退出码。从上面的代码中,我们看到在以后的多进程的基础写法就是要靠wait/waitpid。
pid_t waitpid(pid_t pid,int*status,int options);
其中:1.pid=-1等待任意一个子进程与wait
2. pid>0,等待其进程ID与pid相等的子进程
这上下两个都可以
status:输出型参数,status并不是按整数来整体使用的,而是按照32位来进行划分,在这里我们只看低16位。
程序异常退出或者崩溃的本质时:OS杀掉了你对进程。
OS是怎么杀掉呢?答:本质是通过发送信号的方式,OS发送不同的信号来杀死我们的进程。
为什么父进程可以通过wait函数来拿到子进程的结果呢?
因为进程具有独立性,那么数据就要发生写时拷贝,父进程就无法拿到,调用wait函数本质其实就是读取了子进程的task_struct结构
我们知道僵尸进程:至少是会保留该进程的PCB信息的,task_struct里面就保留任何进程退出时的退出结果信息
总结
了解了有关wait函数,了解了多进程的控制和结束的使用。
6月19号