进程控制(上)【Linux操作系统】
进程控制写时拷贝
本质是一种镌汰深拷贝的方法
Linux中有很多拷贝的场景都用得上写时拷贝,下面以创建子进程时的写时拷贝为例:
子进程被创建的时间:
会继承父进程的mm_struct和页表
所以子进程刚刚继承时,父子进程的代码和数据都是共享的
系统是怎样知道子进程/父进程修改数据的时间要发生写时拷贝的呢?
①父进程在使用fork创建子进程之前,就会把页表中的数据区的权限改成r(只读)
如许子进程继承到的页表中的数据区就也是只读的
②当子进程/父进程尝试修改数据区中的数据时,就是修改只读数据项,页表就会报错,就会触发缺页中断
③系统发现缺页中断之后,就会检测
1,假如发现用户要修改的这个地区肯定是只读的,就把进程杀掉
2,假如这个地区肯定是读写的,只是页表中的权限设置成只读的了,此时系统就会举行写时拷贝
https://i-blog.csdnimg.cn/direct/8a649680e9624e73aa3f44f62b64918b.png#pic_center
所以:不止创建子进程写时拷贝的时间是这种原理
只要可能发生写时拷贝的数据被页表管理着,就都可以通过这个原理实现写时拷贝
错误码
用来判定进程任务执行是否成功,假如失败了错误是什么
main函数的返回值实在是错误码,是返回给父进程/操作系统的
https://i-blog.csdnimg.cn/direct/cfe80da899f344febe2112c1042d8b7f.png#pic_center
进程错误码的的取值范围是,即一个字节
由于使用wait/waitpid等待回收错误码的时间,只给它留了8个比特位
进程中断
进程中断的方法:
①在main函数中return
②在任何地方使用exit函数
③_exit使用方法和exit一模一样
exit与_exit的区别:
①本质区别就是exit是用户层的库函数,_exit是内核层的系统调用
所以exit函数中,调用_exit中断进程之前,可以举行一些用户层的收尾工作
好比:
exit中断进程时,会革新用户级缓冲区和内核级缓冲区
也就是假如输出缓冲区中有数据,使用exit中断它会帮我们打印出来
_exit中断进程时,不会革新用户级缓冲区,只会革新内核级缓冲区
②exit是库里面的函数,是操作系统之外的操作,使用操作系统的资源时,只能对操作系统调用接口举行封装
exit实在就封装了_exit
_exit是系统调用接口,是操作系统内部的操作
https://i-blog.csdnimg.cn/direct/0d128fd348964ef986b01a663822b894.png#pic_center
所以:
实在我们之前再使用c/c++等高级语言时,所说的缓冲区都是语言级(用户级)的缓冲区
这个缓冲区里面的内容是存储在c/c++的标准库中的,即存储在共享区的
不是存储在操作系统中的内核级缓冲区
否则_exit中断进程时,就也能把缓冲区中信息输出/输入
但是由于语言级缓冲区在操作系统的上层,所以_exit中断进程后,内核缓冲区就关闭了,语言缓冲区中的数据没办法进入操作系统了
操作系统没瞥见语言缓冲区中传来信息,就以为里面没有
进程等待
wait(不常用)
头文件:sys/types.h和sys/wait.h
返回值:pid_t[小于0分析回收失败,大于0时回收成功,返回的是回收的子进程的pid]
参数:
作用:等待并回收任意一个子进程
https://i-blog.csdnimg.cn/direct/25ab89e0a5504049a5987b1897a1b71a.png#pic_center
waitpid[常用]
头文件:sys/types.h和sys/wait.h
返回值:pid_t n
①n小于0,分析回收失败/函数调用失败
②n大于0,回收成功,返回的是成功回收的子进程的pid
③n等于0(只有非壅闭等待才会出现),则体现函数调用成功,但是子进程还没执行完,还没退出
参数1.pid_t pid
假如是子进程的pid,就体现指定等待这个子进程
假如是-1,就体现等待任意一个进程
参数2,int* status
假如传nullptr则体现不必要获取退出信息==
即:用户本身定义一个int类型的变量
再把它的地点传进waitpid里面,操作系统就会把进程的PCB中存储的退出信息给status
status实在并不是一个整数,而是一个类似位图的东西
由于进程结束,分两种情况:
①正常退出,也就是通过main函数的return或者exit退出,如许就可以返回退出码
所以只有正常退出才能返回退出码(错误码)
②非常退出,也就是进程运行的途中,空指针访问/野指针等直接导致进程崩溃了
如许进程根本就运行不到返回退出码的地方
但黑白常退出,也会有本身的退出信号码
[通过kill -l命令,可以看到Linux中全部的退出信号以及其对应的退出信号码]
进程之所以会非常退出,是由于进程运行时出现了较严重的错误(野指针,除0等)
操作系统辨认到以后,在代码还没跑完的时间,就直接使用信号中断了进程
所以
status中不但仅存储了退出码,还存储了其他的退出信息
详细的:
status的:
①最低的7个比特位存储退出信号值
②第8个比特位存储core dump标志
③第9~16个比特位存储退出码
https://i-blog.csdnimg.cn/direct/8ae984836f51490886fab8110bf1dc00.png#pic_center
宏:
WIFEXITED(status):
若为正常终止子进程返回的状态,则为真(查看进程是否是正常退出)
WEXITSTATUS(status):
若WIFEXITED非零,提取子进程退出码。(查看进程的退出码)
参数3.标识是壅闭等待,还黑白壅闭等待
假如该参数是0,体现壅闭式等待
假如为WNOHANG,体现非壅闭式等待
使用子进程完成任务的利益
①非壅闭等待或者创建多个子进程时,父子进程可以同时运行,父进程不用等子进程,进步并发度
②进程具有独立性,所以假如子进程出了问题,不影响父进程
③数据快照,子进程被fork出来,继承了父进程的PCB,页表等东西之后
就获取到了fork时父进程的数据
也就是对子进程从父进程那边获取到的数据举行了快照
快照之后,其他任何进程对这一块数据举行修改,这个子进程都“看不见”
由于写时拷贝,或者说进程具有独立性。所以数据快照之后,其他进程可以对这个数据任意修改
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页:
[1]