IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 系统运维 -> Linux——僵尸进程以及僵尸进程的处理 -> 正文阅读

[系统运维]Linux——僵尸进程以及僵尸进程的处理

僵尸进程

(1)进程中的指令已经执行完成,但是进程PCB结构还没有回收。
即子进程先于父进程退出后,子进程的PCB需要其父进程释放,但是父进程并没有释放子进程的PCB,这样的子进程就称为僵尸进程。
(2)父进程未结束,子进程结束,但父进程没有处理子进程的退出状态(当子进程先于父进程结束,父进程没有获取子进程的退出码,子进程的PCB会保留一段时间等待父进程在PCB中获取退出码,,且该进程不可执行,此时子进程变成僵尸进程)。
直到父进程获取到子进程的退出状态,子进程的PCB才会被移除。

我们的程序在退出的时候:return 0,exit(0),这个0就是退出码(状态信息),它存储在当前进程的PCB中,会有一个整型值来存储退出码。
当我们子进程结束以后,会把退出码写到PCB中,然后希望父进程可以获得到这个退出码,然后父进程就可以看到子进程是正常运行结束还是出错退出。正常的话我们return 0,失败的话我们return -1。

模拟僵尸进程:
在这里插入图片描述

僵死进程产生了,会有什么影响?

  • 如果只有一两个僵死进程,没有什么影响。
  • 如果有很多个僵死进程,持续不断的产生,就有影响了,因为子进程的PCB如果没有被释放,进程的PID就被一直占着,在内核空间中,PCB本身是结构体,会占用内存空间,对系统软硬件资源损耗,因此我们要避免僵死进程的产生,父进程有义务去处理!

如何处理僵尸进程

  1. 父进程调用wait()方法获取子进程的退出码,从而使得OS删除子进程的PCB;
  2. 父进程先结束(该子进程就失去了父进程,系统会将这种没有子进程的父进程当做孤儿进程OS会给该孤儿进程重新寻找一个父进程Init进程,其PID == 1,通常会收养那些没有父进程的子进程,就会直接获取其退出码从而消除该进程的僵死状态 [ 其内部其实也是调用了wait()方法] )
  3. 如下图所示,修改之前的代码,让父进程先于子进程结束
    在这里插入图片描述
    执行结果如下:
    在这里插入图片描述
    我们可以看到失去父进程的子进程的PPID变为1,也就是Init进程
    在这里插入图片描述

父进程处理子进程退出状态(退出码)的方法:

pid_t wait(int *result)//获取调用此方法的进程的子进程的退出码
  • 如果没有子进程,则调用失败;
  • 如果有子进程并且已经结束,则返回子进程的PID,退出码在result带回。
  • 如果子进程没有结束,那么wait就会阻塞等待子进程结束。

我们来看一下wait的参考手册:
在这里插入图片描述
我们需要传入一个整形变量的地址,它会将退出码写到该地址中,返回值就是他获取到退出码的那个子进程的PID。
在这里插入图片描述执行结果如下:这样就相当于父子进程是串行执行的,因此我们不会很简单粗暴地调用wait(),失去了多进程执行的意义,常会使用一些巧妙的方法,比如配合信号使用,这个在后面的博客中将会提到。

出现这种现象的原因是:父进程需要获取子进程的退出码,就需要等待子进程先结束,既然子进程没有结束,就无法获取子进程的退出码,wait()方法就相当于阻塞了父进程的运行。

在这里插入图片描述

  • 如果有多个子进程,一次wait调用只能处理一个子进程(最先结束的哪一个)。

如下代码也用wait处理了僵尸进程,但我们需要解决另外一个问题:
注意:此时我们exit(0)的退出码是0
在这里插入图片描述
此时val的值为0在这里插入图片描述
但是当我们将退出码改为3时,执行结果发生了变化,我们可以看到val = 768
在这里插入图片描述
这是为什么呢?
其实768对应的二进制数为0011 0000 0000,(11就是那个3)
——左移了8位,因为退出码一般来说是128以内的值,但是一个整型有4字节,1个字节本来就够存储退出码了,其他3个字节有别的作用了,所以在这里就发现被移位了,存储在该存储的位上。我们这怎么处理?操作位是不大方便的,但是系统给我们提供了一些方法

  • 第一个宏是用来判断程序是否是正常exit退出
  • 如果是正常退出,就通过第二个宏得出退出码,这个宏就知道我们的退出码是在4个字节中的哪个字节存放的,精准取值,此时拿到的就是我们设定的3了,不是768了。

在这里插入图片描述
当程序还没有执行到exit就被杀死,获取到异常终止的信号,我们就用下面这个宏来判断
在这里插入图片描述
使用宏后,我们修改代码如下:
在这里插入图片描述
之后就可以看到正常的执行结果了
在这里插入图片描述

wait调用的最佳时机:子进程退出的那一时刻,父进程调用wait;
这里引入一个概念,在下一期Linux专栏将会讲到信号

若在父进程一开始就调用,那么就会出现串行执行的效果;
若在父进程快要结束的时候调用,那么父进程已经退出,处理僵尸进程就没有意义了。

  系统运维 最新文章
配置小型公司网络WLAN基本业务(AC通过三层
如何在交付运维过程中建立风险底线意识,提
快速传输大文件,怎么通过网络传大文件给对
从游戏服务端角度分析移动同步(状态同步)
MySQL使用MyCat实现分库分表
如何用DWDM射频光纤技术实现200公里外的站点
国内顺畅下载k8s.gcr.io的镜像
自动化测试appium
ctfshow ssrf
Linux操作系统学习之实用指令(Centos7/8均
上一篇文章      下一篇文章      查看所有文章
加:2022-01-16 13:31:42  更:2022-01-16 13:31:57 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/16 6:43:37-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码