网站付的保证金怎么做会计凭证,无锡2019网站建设报价清单,苏州市著名网站制作,山东手机在线app大家好#xff0c;我是苏貝#xff0c;本篇博客带大家了解Linux进程#xff08;9#xff09;进程控制1#xff0c;如果你觉得我写的还不错的话#xff0c;可以给我一个赞#x1f44d;吗#xff0c;感谢❤️ 目录 1 fork函数2 进程终止#xff08;A#xff09;终止是… 大家好我是苏貝本篇博客带大家了解Linux进程9进程控制1如果你觉得我写的还不错的话可以给我一个赞吗感谢❤️ 目录 1 fork函数2 进程终止A终止是在做什么B退出码C进程退出的3种情况D 如何终止进程1 main函数return表示进程终止非main函数return表示函数结束2 代码调用exit函数3 _exit函数 ---系统调用 1 fork函数 如果fork出错那就不创建子进程给父进程返回-1
为什么给父进程返回的是子进程的pid 为了让父进程方便对子进程进行标识进而进行管理
如何理解进程具有独立性 进程内核的相关管理数据结构task_structmm_struct页表代码和数据。对于不是父子进程的多个进程上面的5个都不同自然具有独立性。对于父子进程task_struct自然不同子进程的mm_struct和页表都是拷贝父进程的但每个进程都有自己独立的mm_struct和页表所以也互不影响代码是共享的也是只读的所以父子进程互不影响对于数据父子不写入时数据也是共享的如果其中一个进程想要对数据进行写入会发生写时拷贝因此父子进程也互不影响。所以父子进程也具有独立性所以进程具有独立性
2 进程终止
A终止是在做什么
释放曾经的代码和数据所占据的空间释放内核数据结构mm_struct和页表的空间但是task_struct会维持一段时间变成Z状态僵尸状态进程要维持自己的退出信息退出信息位于task_struct中未来让父进程进行读取
B退出码
退出码是在进程执行结束后系统返回给使用者的一个数值用以表示进程的执行状态。main函数最后的return后面的数字是退出码。
所以上面代码的退出码就是0那如何查看退出码呢用echo $?命令Linux提供了一个专门的变量?来保存父进程获取的最近一个子进程的退出码
修改.c文件
退出码应该为100 上面说?是保存父进程获取的最近一个子进程的退出码那为什么第二次?的值是0呢
第二次的?是保存第一个echo $?的退出码虽然echo不是bash的子进程但也是由bash执行的所以照样可能会影响退出码。因为第一个echo $?运行成功所以退出码为0
退出码有什么用呢 告诉关心方一般为父进程进程把任务完成的怎么样了。 如果退出码为0表示程序运行成功为!0表示失败。不同的!0值一方面表示失败一方面也表示失败的原因即有对应的错误描述
现在我们来看看退出码对应的错误描述
先看strerror函数作用返回错误码的字符串描述。参数是错误码
修改.c文件
0表示成功1表示操作不被允许2表示没有该文件或目录……
关于退出码我们可以选择使用系统默认的也可以使用我们自定义的。 我们来试试用自定义的退出码
修改.c文件
但我们发现如果result-1我们不能确定是y 0还是y! 0x/y -1
修改.c文件
如果result-1错误码 1那么说明y 0。如果result-1错误码 0说明x/y -1
因此退出码可以确定代码跑完结果是否正确。所以你是否感觉到以前写的代码都不是很规范呢有没有正确使用退出码呢
C进程退出的3种情况
代码跑完结果正确代码跑完结果不正确代码执行时出现异常提前退出了
前2个可以根据退出码判断就不再赘述了。现在我来看看第3种情况代码执行时出现异常提前退出了
我们之前在写代码的时候一定遇到过程序崩溃的情况吧。崩溃是语言层面说的在系统层面是因为操作系统发现你的进程做了不该做的事情所以将进程杀掉了。
所以进程出异常的本质是因为进程收到了OS发给进程的信号
现在我们来用野指针让进程出异常
出现异常并报错Segmentation fault表示段错误。OS提前终止进程
上面说进程出异常的本质是因为进程收到了OS发给进程的信号现在让我们来感受一下
修改.c文件
该进程正常来讲的话是不会有异常的
再使用kill的11号信号
此时尽管代码没有错误但是由于进程收到了系统的信号所以判断是 Segmentation fault段错误标识进程提前终止了。因此我们也可以感受到进程出异常是因为进程收到了OS发给进程的信号
因此我们可以通过看进程退出的时候退出信号是什么来判断我的进程为什么异常了。如果进程没有异常代码跑完了那退出信号为0 请问如果进程出现异常提前退出了那还需要知道退出码吗不用了进程出现异常退出码就没有意义了
如何确定程序退出是3种情况的哪一种呢
先确认是否异常不是异常就是代码跑完了看退出码判断结果是否正确
结论衡量一个进程退出我们只需要知道2个数字退出码和退出信号 退出码为0退出信号为0代码跑完了结果正确 退出码为!0退出信号为0代码跑完了结果不正确 退出码为0退出信号为!0进程出现异常 退出码为!0退出信号为!0进程出现异常
一个进程结束系统会释放它对应的代码和数据的空间释放内核数据结构mm_struct和页表但是task_struct会维持一段时间变成Z状态僵尸状态系统会将进程的退出码和退出信号写入进程的task_struct中等待父进程进行读取
D 如何终止进程
1 main函数return表示进程终止非main函数return表示函数结束
2 代码调用exit函数
先了解exit函数作用让一个正常的进程终止参数是退出码
修改.c文件
退出码123
上面说main函数return表示进程终止非main函数return表示函数结束。那如果是在非main函数中调用exit函数是表示函数结束还是进程终止呢
修改.c文件
运行程序先进入Div函数因为100!0所以执行代码exit(13)
进程并没有打印main函数的printf函数里的内容所以在非main函数中调用exit函数是进程终止。 所以在代码的任意位置调用exit函数都表示进程退出
3 _exit函数 —系统调用
先了解一下_exit作用终止进程参数也是退出码
修改.c文件
进程也没有打印main函数的printf函数里的内容所以在代码的任意位置调用_exit函数都表示进程退出
那exit函数和_exit函数有什么不同吗
修改.c文件
结果先等待2秒再打印出”hello world”这说明exit函数会冲刷缓冲区
修改.c文件
结果等待2秒后不会打印”hello world” 这说明_exit函数不会冲刷缓冲区
exit vs _exitexit函数会冲刷缓冲区而_exit不会。 这说明我们所说的缓冲区不在OS内即不是内核缓冲区。
理由 exit底层调用的就是_exit因为杀掉进程本质就是释放进程对应的代码和数据释放进程的除pcb以外的其它内核数据结构。总之是对进程做管理的一种方式。但用户没有权利对操作系统内的字段做任何访问包括终止一个进程。因此exit底层一定会调用_exit系统调用 如果缓冲区在操作系统exit能冲刷缓冲区那么_exit也能因为exit底层调用的就是_exit。但是_exit不能因此缓冲区不在OS内即不是内核缓冲区而在_exit之上exit先冲刷缓冲区再调用_exit 好了那么本篇博客就到此结束了如果你觉得本篇博客对你有些帮助可以给个大大的赞吗感谢看到这里我们下篇博客见❤️