全国优秀作文网站,做同城特价的网站,dede58织梦模板,网站的内容管理系统在上一小节中我们介绍了进程的创建#xff08;fork#xff09;与退出#xff08;main函数的return与exit函数#xff09;
并且要有一个意识#xff0c;进程退出的时候只有三种情况#xff1a;
1.进程退出#xff0c;结果正确
2.进程退出#xff0c;结果不正确
3.运行异…在上一小节中我们介绍了进程的创建fork与退出main函数的return与exit函数
并且要有一个意识进程退出的时候只有三种情况
1.进程退出结果正确
2.进程退出结果不正确
3.运行异常收到信号退出文章目录 1.进程等待2.wait/waitpid1). wait2). waitpid 2.进程等待如何完成它的任务1). 进程等待解决僵尸进程内存泄漏2). 进程等待如何收到子进程退出信息3). 从系统层面大致了解父进程获取子进程退出信息信息 3.阻塞等待 现在我们还需要认识一个函数_exit函数 可以看到它在二号手册里所以它是系统调用函数。它也能够终止进程。用法跟exit函数一样那它与exit函数有什么区别呢代码演示一下 exit函数 _exit函数 我们发现exit函数会先刷新缓冲区的内容到屏幕上然后再退出进程但是 _exit函数是直接退出没有刷新缓冲区内容并且exit函数是标准库函数_exit函数是系统调用函数由此我们可以得到exit函数是封装了_exit函数内部还有诸如刷新缓冲区这样的其他的工作。 我们知道库函数系统调用操作系统内核是这样的关系exit函数刷新缓存区_exit函数没有刷新缓存区那么我们也可以得到一个结论我们所认知的缓存区不在操作系统内部。这就是进程退出所用到的函数。
说明虽然_exit的参数是int但是仅有低8位可以被父进程所用。
所以_exit(-1)时在终端执行$?发现返回值是255。1.进程等待
当一个进程退出后没有被回收那么它就会进入僵尸状态并且它的父进程不回收它的话这个进程会一直存在会发生内存泄漏。那么进程等待的一个任务就是为了解决僵尸状态伴随的内存泄漏。 那么什么是进程等待呢
它其实是使用wait/waitpid的方式来实现父进程对子进程资源回收的等待过程。为什么要进程等待上面已经说过
1.为了解决僵尸状态不回收造成的内存泄漏问题。
2.要知道子进程把任务完成的怎么样因为什么终止退出退出码和接受信号这一点不是必要的。比如一些场景下父进程是不需要子进程把任务完成与否子进程因为什么而退出、终止的。
2.wait/waitpid
1). wait wait是一个系统调用函数它有一个参数我们稍后再说。它会回收任意一个子进程并会返回回收进程的id。 我们现在来展示一下任意这两个字的含义 我们这里创建了五个子进程所以掉用五次wait。 可以看到操作系统调度进程是不确定的wait回收进程也是不确定的。
2). waitpid waitpid可以看到有三个参数第二个参数和第三个参数也先不说那么显然它是专门回收特定进程的当它的参数是下面红框中的那样的时候它和wait没有区别当waitpid第一个参数小于零的时候它也是回收任意一个子进程。 2.进程等待如何完成它的任务
1). 进程等待解决僵尸进程内存泄漏
我们先搞出一个僵尸进程
然后使用wait回收这个进程 2). 进程等待如何收到子进程退出信息
这就谈论到wait和waitpid中的int* status这个参数了。我们用C语言做题的时候也会碰到这样的接口 这种叫做输出型参数目的是调用这个接口带回来某些东西而这里的status带回来的就是退出码和子进程异常终止收到的信号。 话不多说代码展示 这里退出码是0 退出码为10 我们看到我们的退出码是10但是打印出来的是2560。 我们再用一个11号信号来终止子进程 发现status的值又是10。 我们说了这个变量可以接收到退出码和异常终止的信号而这两个是两个东西所以我们的status不是一个单纯的int变量而是一个32个比特位的二进制数字而我们也只用它的低十六位 那我们现在来验证一下是否真的是我说的这样呢我们只需要对status进行位运算就可以 确实是我们说的那样。那么说明wait/waitpid确实可以接收退出码和终止信号。 那我们可以这样写 但是这里介绍两个宏 WIFEXITED(status) 若此值为非0 表明进程正常结束。 若上宏为真此时可WEXITSTATUS(status)获取进程退出状态。
3). 从系统层面大致了解父进程获取子进程退出信息信息
我们知道进程间具有独立性所以我们无法通过一个简单的变量来获取子进程的退出信息因为同一个变量但凡有一个进程改变它的值都会发生写时拷贝所以需要系统调用来实现。 子进程在退出的时候会把代码数据销毁之后将退出信息写到自己的pcb结构体中并将状态改为Z然后等待父进程回收而父进程使用wait/waitpid回收后才可以释放子进程pcb。
3.阻塞等待
我们前面的的代码都是父进程等到子进程结束后再开始回收子进程那直接回收呢 我们看到父进程回收的时候是一直在等待子进程结束之后才进行的回收才会执行后续的代码这就是阻塞等待。这就涉及到waitpid的第三个参数 当这个参数值为0时就是阻塞等待。 当这个参数为WNOHANG一个#define的常量时是非阻塞等待
在这里我们发现它返回了一个值是0但是应该是子进程的id才对这里返回值有了不一样的解释
返回值大于0等待成功
返回值等于0等待成功但是子进程还没有结束
返回值小于0等待失败例如等待一个不存在的进程所以当我们使用非阻塞等待时需要以一个循环的方式多次等待而我们也可以再这个循环里做一些父进程比较简单的任务。