目录 :
1.fork()写实拷贝 -- 缺页中断
2.进程终止
1.退出码
2.exit(进程终止)、_exit()
3.进程等待
1.进程等待的必要性
2.进程如何进入等待
------------------------------------------------------------------------------------------------------------------------------
1.fork()写实拷贝
我们的父子进程是怎么做到写实拷贝的呢???--------我们今天可以站在地址空间的角度来看待这个问题
我们以下面这张图为例 -- 对写实拷贝进行分析
图中我们的页表是简化后的,真是的页表可是非常的复杂的
我们的地址空间上可是有2^32次方个虚拟地址的,我们的页表不就是虚拟地址到物理地址的映射嘛,如果一个虚拟地址的大小是6字节,那么我们2^32次方是4GB,那么总共就需要24GB的空间,这仅仅只是一个进程的页表所需的大小,页表也是在内存当中的(我们的内存也就4GB),所以本身也不一定全部加载到内存的,在需要的时候才加载到内存的
缺页中断:当一个进程往一个不可写的内存当中写入了,操作系统检测到那么就会发生一个中断
操作系统会自动发生写实拷贝将你的数据分开,确保进程的独立性
----------------------------------------------------------------------------------------------------------------------------
2.进程终止
1.退出码
进程退出场景:
代码运行完毕,结果正确
代码运行完毕,结果不正确
代码异常终止
--------------------------------------------------------------------------------------------------------------------------
main函数为什么都要有一个return 一个值呢???
这个值是进程的退出码 !!!这个退出码是可以被父进程或系统所获取的
退出码的意义
代码跑完,结果正确,我们用0表示,可是为什么代码跑完我们用非0表示呢???
原因是结果不正确我们更想知道结果为什么不正确,可不正确的原因有多种可能的,我们就可以用一种数字去充当一种可能性
代码异常终止
2.exit(进程终止)
main函数return代表进程退出了!!!!! 那如果是非main函数呢也就是说一个函数退出了,它不是main函数
非main函数返回仅仅代表着函数返回!!!,main函数返回代表着进程退出
我们可以通过一个调用exit终止我们所谓的一个进程
我们的代码是在运行完函数fun之后执行exit()终止退出码设置为12,这叫做进程终止
exit在任意的地方调用,都会导致我们的进程退出,哪怕我们没有在main函数里调用exit在fun函数里调用exit也会导致我们的进程退出
exit在任意地方调用,都代表这进程终止,参数是退出码 !!!
3._exit
_exit终止进程,强制终止进程,不要进行进程的后续收尾工作,比如刷新缓冲区!!!
进程退出, OS 层面做了什么???
在系统层面,少了一个进程:free、PCB 、mm_struct 、 free页表和各种映射关系,代码+数据申请的空间也要给释放掉!!!
3.进程等待
1.进程等待的必要性
为什么要让父进程等待呢???
1.通过获取子进程退出的信息,能够得知子进程执行结果。
2.通过等待可以保证: 时序问题,子进程先退出,父进程后退出
(不然我父进程比你子进程先退出,那我父进程还怎么获取你子进程的退出信息啊!!!)
3.进程退出(尤其是子进程)退出的时候,会先进入僵尸状态,会造成内存泄漏的问题,需要通过父进程wait,释放该子进程占用的资源!!!!!
2.进程如何进入等待
wait -- 等待一个进程死掉,你本来是一个活着的状态,直到你的状态变成了Z状态,我才有可能再去读取你的信息,进而返回
wait的返回值 --------- 等待成功返回你等待成功的进程PID ,等待失败 -1 被返回
-----------------------------------------------------------------------------------------------------------------------------
所以我们写一段代码
上面的代码也验证了我们的wait可以处理我们的僵尸进程的回收
wait并不是我们的重点,我们另一个重要的接口 waitpid()这个接口提供的功能更丰富
waitpid返回值一样的是 等待成功返回等待成功的哪个进程的PID ,失败返回 -1
跟我们预期的结果一样!!!!!
上面我们是指定一个进程等待,那我们如何让父进程等待任意一个进程呢
如何让父进程通过等待获取子进程的退出信息呢????
这边导致我们期望的结果不是12,又该如何理解呢???
所以实际上我们是需要有两组信息,被我们所获取到,一个进程退出码,一个信号
如果没有收到信号,那么我们的程序是正常跑完的,再来关心我们的退出码,否则不关心退出码
那么其中次低8位,也就是进程退出的退出状态(传说中去退出码),第七个比特位代表着进程终止时所收到的信号,大部分情况下都0
所以我获得的status是由32个比特位构成的,我们的次低8位对应着我们进程退出时的退出码,那么我们的第七位代表着我们的进程收到的信号,那么只要将来我们收到的退出码时,第七位是0,代表着没有收到信号,这个进程是正常运行完的,运行完了对还是不对,通过次低8位获得。。。