Linux进程概念僵尸进程孤儿进程

news2024/12/23 12:20:30

文章目录

    • 一、什么是进程
    • 二、进程的状态
    • 三、Linux是如何做的?
      • 3.1 R状态
      • 3.2 S状态
      • 3.3 D状态
      • 3.4 T状态
      • 3.5 t状态
      • 3.6 X状态
      • 3.7 Z状态
    • 四、僵尸进程
      • 4.1 僵尸进程危害
    • 五、孤儿进程

一、什么是进程

  • 对于进程理解来说,在Windows上是也可以观察到的,右键状态栏的任务管理器就可以看到

在这里插入图片描述

  • 运行一个进程是需要占用CPU和内存的
  • 在我们平时运行一个进程的时候(Windows)直接双击后,系统将磁盘里的exe文件加载到内存当中,这个时候就当运行起来的时候就开启了一个进程,这里要注意,加载到内存中中是不算进程的,只有当运行起来后才算是进程 -->进程 = PCB + 自己的代码和数据
  • 对应的每一个进程都有一个PCB结构体,操作系统需要通过此结构体找对应的二进制
  • 当有多个进程被运行起来的时候,就会产生多个PCB结构体,这个时候需要组织(可以是链表或者其他更高效的数据结构)起来进行管理,这就产生一个重要的概念------->先描述,再组织

在这里插入图片描述

  • 每个进程都对应的每个PCB结构体,当运行的时候需要进行排队,CPU就可以通过PCB找到原代码,再把代码交给CPU运行

在这里插入图片描述

二、进程的状态

  • 每个进程都有自己的一个状态,告诉操作系统正在干什么,将来要干什么?也就是说,进程的多种状态,本质都是为了满足未来的某种使用场景。

  • 就比如Windows上的任务管理器也有显示进程的状态

在这里插入图片描述


  • 在操作系统上有三种状态
    • 运行状态
    • 挂起状态
    • 阻塞状态

  • 运行状态:从计算机的硬件出发,我们所写的代码在硬盘中,要让程序运行起来就要加载到内存当中, 每一个程序(进程)都会有一个属于自己的PCB,通过PCB来进行排队,等待CPU的调度,为了方便调度管理,操作系统会维护一个运行队列,所有就绪状态的进程的PCB会被加入到这个队列当中, CPU在调度执行时就会通过这个运行队列拿到进程的PCB,进而调度执行该进程,在排队的时候就是运行状态。

  • 挂起状态:内存满负荷时,又要增加新的进程显然是不行的。所以操作系统会观察内存中的哪些进程没有被放在任何一个队列里面(在内存里面啥也不干),找到以后就把此进程的代码和数据短期内置换到磁盘上,仅保留此进程的PCB。腾出的这一块空间供新的进程使用。针对于这种情况,操作系统会将阻塞进程的代码和数据置换到外设,此时该进程的状态就被称为挂起状态;

    • 其中阻塞进程的代码和数据一般会存放在磁盘的swap分区,当进程被操作系统调度时,被置换到外设的代码和数据又会重新加载到内存;

    • 一般情况下,swap分区的大小不会太大,大概等于内存的大小,过大的swap分区会导致操作系统过于依赖swap分区,导致效率变低;


  • 阻塞状态:在CPU执行一个进程的时候,可能会需要访问系统的某些资源,就比如在C语言中写的scanf(),在使用这个函数的时候,需要调用键盘,等待键盘输入数据,当进程需要键盘资源的时候,会将进程的PCB加入到硬件设备结构描述的等待队列当中,并且把PCB设置为阻塞状态,当PCB在这个等待队列中等待数据资源时,这个状态就叫做阻塞状态;

三、Linux是如何做的?

  • 在Linux内核中是这样定义的:
/*
* The task state array is a strange "bitmap" of
* reasons to sleep. Thus "running" is zero, and
* you can test for combinations of others with
* simple bit tests.
*/
static const char * const task_state_array[] = {
	"R (running)", /* 0 */
	"S (sleeping)", /* 1 */
	"D (disk sleep)", /* 2 */
	"T (stopped)", /* 4 */
	"t (tracing stop)", /* 8 */
	"X (dead)", /* 16 */
	"Z (zombie)", /* 32 */
};
  • 先简单描述一下这些状态:

    • R (Running):该进程正在运行中。
    • S (Sleep):该进程目前正在睡眠状态,但可以被唤醒。
    • D :不可被唤醒的睡眠状态,通常这个进程可能在等待I/O的情况。
    • T :停止状态,发送一个暂停信号给进程,进程就暂停了。
    • t :追踪停止状态,通常在断点调试时,进程处于此状态。
    • X :死亡状态,这个状态是用来告诉操作系统的,所以我们观察不到此状态。
    • Z (Zombie):僵尸状态,进程已经死亡,但是却无法被删除至内存外。

  • 下面我们挨个介绍一下,以下用Linux来查看:

在这里插入图片描述

  • 这里我们还需要了解一个概念,进程是有依赖的,就比如我运行这个C语言程序,其父进程是bash,pid是本进程的id,ppid是父进程的id

在这里插入图片描述

3.1 R状态

  • 下面我们编写这样一段代码,是一个死循环,这样可以观察到进程
#include<stdio.h>
#include<unistd.h>
int main()
{
  while(1){

  }
  return 0;
}

  • 普通查看进程可以这样查看
ps -aux | head -1 &&ps -aux | grep a.out

在这里插入图片描述

  • 我们还可以用shell命令来一直刷新观察
while :; do ps ajx | head -1 && ps ajx | grep a.out | grep -v grep; sleep 1; done

在这里插入图片描述

  • 这里看到是R+是代表在前台运行,在运行的时候可以使用ctrl+c进行中断,中断后进程也就退出了

  • 我们可以让此程序到后台运行

    • 在命令后面加“&”符号

    • 这里的pid进程id是唯一的,标识此进程,ppid代表父进程

在这里插入图片描述

  • 在运行起来后看到那个+号就没有了,说明是在后台运行中

在这里插入图片描述

  • 想要杀死这个程序就需要使用kill命令来进行杀死
kill -9 27165
  • 这里使用kill -9命令比较麻烦需要找到进程的id,我们还有一个命令
killall -9 a.out
  • 这样就可以不用输入进程id输入此进程的名字即可

  • 我们再补充一个概念,每一个进程运行起来的时候都有一个文件被创建

  • 在根目录下的proc

在这里插入图片描述


3.2 S状态

  • 这个状态表示此进程正在睡眠,但是可以被唤醒

  • 下面可以进行演示一下:

#include<stdio.h>
#include<unistd.h>
int main()
{
  while(1){
	printf("hello world\n");
  }
  return 0;
}

  • 在上面的那段代码中添加了一个printf打印函数,同样是运行,但是这里为什么是S状态呢?

在这里插入图片描述

  • 这是因为CPU运行的速度很快,一直需要请求显示器响应,CPU多数的时候是在等待,所以就显示S

3.3 D状态

  • 此状态是深度休眠状态,不可被唤醒,是为磁盘准备的

  • 当进程需要大量的数据写入磁盘的时候,等待磁盘写入的进程状态就是休眠,上面也将过了,

  • 在内存严重不足的情况下,操作系统没办法时会通过杀死进程的方式来节省资源;如果在等待的过程中进程被操作系统杀掉,并且磁盘写入数据失败,那么就会导致数据无法再加载(数据丢失);为了避免这种情况,就可以把等待数据写入的进程状态设为D状态;

  • D状态无法被杀掉(OS也不行),只能等待执行完毕后状态转换;


这个D状态不好验证,如果看到此状态说明计算机就要快挂了~~


3.4 T状态

  • 此状态是停止状态,可以通过发送 SIGSTOP 信号给进程来停止(T)进程。这个被暂停的进程可以通过发送 SIGCONT 信号让进程继续运行

在这里插入图片描述

在这里插入图片描述

  • 可以使用kill -l命令查看一下发送信号的类型

在这里插入图片描述


3.5 t状态

  • 这个小写的t状态也是停止状态

  • 主要出现在程序Debug时,在Debug的时候,遇到断点,进程就暂停,此时就是t状态

  • D状态、T状态、t状态其实都是阻塞状态,阻塞可以等待硬件资源也可以等待软件资源


3.6 X状态

  • X状态(死亡状态),就是我们常说的终止状态,它是一个瞬时状态,不会在任务列表里看到这个状态

3.7 Z状态

  • 最后就是Z(zombie)僵尸状态,僵尸状态较为复杂,Linux系统中的僵尸进程状态也是一种特殊的进程状态,通常是指一个子进程已经结束运行,但其父进程还未对其进行善后处理。如果不及时清理僵尸进程,会导致系统资源泄漏,影响系统性能甚至造成系统崩溃;

四、僵尸进程

  • 当有一个进程要退出的时候,它是直接原地消失、释放空间的吗?

  • 当进程退出的时候,它是不会立即释放空间的,它的PCB会保存一段时间让父进程或者操作系统读取,让父进程或操作系统知道这个进程即将退出了,然后父进程或者操作系统释放掉进程占用的资源和空间。一般情况下,清理进程资源空间的操作都是父进程。

  • 那么僵尸进程,指的是什么呢?就是进程退出时,依然会在内存里面待一段时间,如果父进程没有能力将此进程完整地释放掉,造成这个进程一直在内存里面,此时这个进程就是僵尸进程


  • 下面我们创建一个子进程来看一看
#include<stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main()
{
    pid_t id = fork();       
    while(1){
      if(id == 0){
          printf("我是子进程,pid:%d,ppid:%d\n",getpid(),getppid());
          sleep(1);
      }
      else if(id > 0){
          printf("我是父进程,pid:%d,ppid:%d\n",getpid(),getppid());
          sleep(2);
      }
    }                                                                                  
    return 0;
}
  • 使用man 的2号手册可以看到fork的用法,fork有两个返回值
  • 父子进程代码共享,数据各自开辟空间,私有一份(采用写时拷贝)

在这里插入图片描述

  • return val这里可以看到返回值,如果成功返回0,失败返回-1,

  • 在程序上面的那个程序的时候,杀死子进程后,子进程的状态就变成了僵尸进程

在这里插入图片描述

  • 僵尸进程通常是无法再进行管理的,所以我们不能直接杀kill掉它,而是交给操作系统来处理这个进程。

4.1 僵尸进程危害

  • 进程的退出状态必须被维持下去,因为他要告诉关心它的进程(父进程),你交给我的任务,我办的怎么样了。可父进程如果一直不读取,那子进程就一直处于Z状态?是的!
  • 维护退出状态本身就是要用数据维护,也属于进程基本信息,所以保存在task_struct(PCB)中,换句话说,Z状态一直不退出,PCB一直都要维护?是的!
  • 那一个父进程创建了很多子进程,就是不回收,是不是就会造成内存资源的浪费?是的!因为数据结构对象本身就要占用内存,想想C中定义一个结构体变量(对象),是要在内存的某个位置进行开辟空间!

五、孤儿进程

  • 孤儿进程,顾名思义,没有父亲的进程就是孤儿进程,也就是,父进程创建了一个子进程,而父进程先退出了,就留下了子进程,这个时候这个进程就叫做孤儿进程

  • 我们再用上面的代码可以演示一下,运行起来后,杀死父进程,就留下一个子进程

在这里插入图片描述

  • 父进程是2200,当杀死父进程后,子进程的ppid就变成了1,就被操作系统接管了

本文介绍了Linux的进程概念,补充了一些概念,最后讲解了僵尸进程和孤儿进程是什么原因造成的

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1508388.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

数据结构与算法第三套试卷小题

1.删除链表节点 **分析&#xff1a;**首先用指针变量q指向结点A的后继结点B&#xff0c;然后将结点B的值复制到结点A中&#xff0c;最后删除结点B。 2.时间复杂度的计算 **分析&#xff1a;**当涉及嵌套循环的时候&#xff0c;我们可以直接分析内层循环即可&#xff0c;看内…

sql注入基础学习

1.常用SQL语句 01、显示数据库 show databases&#xff1b; 02、打开数据库 use db name&#xff1b; 03、显示数据表 show tables&#xff1b; 04、显示表结构 describe table_name&#xff1b; 05、显示表中各字段信息&#xff0c;即表结构 show columns from table_nam…

【框架学习 | 第五篇】SpringMVC(常用注解、获取请求参数、域对象共享数据、拦截器、异常处理、上传/下载文件)

文章目录 1.SpringMVC简介1.1定义1.2主要组件1.3工作流程1.3.1简要流程1.3.2详细流程 1.4优缺点 2.常用注解3.获取请求参数3.1通过 HttpServletRequest 获取请求参数3.2通过控制器方法的形参获取请求参数3.2.1请求路径参数与方法形参一致3.2.2请求路径参数与方法形参不一致3.2.…

笔记本电脑使用时需要一直插电吗?笔记本正确的充电方式

随着科技的不断发展&#xff0c;笔记本电脑已经成为人们日常生活和工作中不可或缺的电子设备。而在使用笔记本电脑时&#xff0c;很多人会有一个疑问&#xff0c;那就是笔记本电脑使用时需要一直插电吗&#xff1f;本文将就此问题展开讨论。 不一定需要一直插电&#xff0c;如果…

C++:2024/3/11

作业1&#xff1a;编程 要求&#xff1a;提示并输入一个字符串&#xff0c;统计该字符中大写、小写字母个数、数字个数、空格个数以及其他字符个数 代码&#xff1a; #include <iostream>using namespace std;int main() {string str;cout << "请输入一个字…

sql-mysql可视化工具Workbench导入sql文件

mysql可视化工具Workbench导入sql文件 1、打开workbench2、导入sql文件3、第一行加上库名4、开始运行 1、打开workbench 2、导入sql文件 3、第一行加上库名 4、开始运行

参与Penpad launch任务,实现Penpad与Scroll的双空投

在比特币 ETF 、BTC 减半等利好消息的持续推动下&#xff0c;加密市场逐渐进入到新一轮牛市周期中。除了以太坊 Layer1 生态 TVL 不断飙升外&#xff0c;Layer2 赛道 TVL 也在不断飙升并且屡创新高。 而在牛市背景下&#xff0c;Layer2 空投所带来的财富效应预期正在被进一步拉…

IAB视频广告标准《数字视频和有线电视广告格式指南》之 目录和概述及视频配套广告 - 我为什么要翻译介绍美国人工智能科技公司IAB系列(2)

写在前面 谈及到中国企业走入国际市场&#xff0c;拓展海外营销渠道的时候&#xff0c;如果单纯依靠一个小公司去国外做广告&#xff0c;拉渠道&#xff0c;找代理公司&#xff0c;从售前到售后&#xff0c;都是非常不现实的。我们可以回想一下40年前&#xff0c;30年前&#x…

Facebook商城号为什么被封?如何防封?

由于Facebook商城的高利润空间&#xff0c;越来越多的跨境电商商家注意到它的存在。Facebook作为全球最大、用户量最大的社媒平台&#xff0c;同时也孕育了一个巨大的商业生态&#xff0c;包括广告投放、商城交易等。依托背后的大流量&#xff0c;Facebook商城起号较快&#xf…

接口测试\接口测试脚本之Jsoup解析HTML

第一次接触jsoup还是在处理收货地址的时候&#xff0c;当时在写一个下单流程&#xff0c;需要省市区id以及详细门牌号等等&#xff0c;因此同事介绍了jsoup,闲来无事&#xff0c;在此闲扯一番&#xff01; 1.我们来看下&#xff0c;什么是jsoup,先来看看官方文档是怎么说的&am…

【深度学习】换脸新科技,InstantID: Zero-shot Identity-Preserving Generation in Seconds

论文&#xff1a;https://arxiv.org/abs/2401.07519 代码:https://github.com/InstantID/InstantID demo&#xff1a;https://huggingface.co/spaces/InstantX/InstantID 文章目录 1 引言2 相关工作2.1 文本到图像扩散模型2.2 主题驱动的图像生成2.3 保持ID的图像生成 3 方法3.…

深入理解Vue.js中的nextTick:实现异步更新的奥秘

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

【wps】wps与office办公函数储备使用(结合了使用案例 持续更新)

【wps】wps与office办公函数储备使用(结合了使用案例 持续更新) 1、TODAY函数 返回当前电脑系统显示的日期 TODAY函数&#xff1a;表示返回当前电脑系统显示的日期。 公式用法&#xff1a;TODAY() 2、NOW函数 返回当前电脑系统显示的日期和时间 NOW函数&#xff1a;表示返…

群晖NAS使用Docker安装WPS Office并结合内网穿透实现公网远程办公

文章目录 推荐1. 拉取WPS Office镜像2. 运行WPS Office镜像容器3. 本地访问WPS Office4. 群晖安装Cpolar5. 配置WPS Office远程地址6. 远程访问WPS Office小结 7. 固定公网地址 推荐 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff…

美国国家安全局(NSA)和美国政府将Delphi/Object Pascal列为推荐政府机构和企业使用的内存安全编程语言

上周&#xff0c;美国政府发布了《回到构建块&#xff1a;通往安全和可衡量软件的道路》的报告。本报告是美国网络安全战略的一部分&#xff0c;重点关注多个领域&#xff0c;包括内存安全漏洞和质量指标。 许多在线杂志都对这份报告发表了评论&#xff0c;这些杂志强调了对 C…

OpenCV学习笔记(五)——图片的缩放、旋转、平移、裁剪以及翻转操作

目录 图像的缩放 图像的平移 图像的旋转 图像的裁剪 图像的翻转 图像的缩放 OpenCV中使用cv2.resize()函数进行缩放&#xff0c;格式为&#xff1a; resize_imagecv2.resize(image,(new_w,new_h),插值选项) 其中image代表的是需要缩放的对象&#xff0c;(new_w,new_h)表…

Python元组(Tuple)深度解析!

目录 1. 什么是元组&#xff1f; 2. 创建元组 3.访问元组 4.元组的运算 5.修改元组不可行 6.元组的应用场景 前面的博客里&#xff0c;我们详细介绍了列表&#xff08;List&#xff09;这一种数据类型&#xff0c;现在我们来讲讲与列表相似的一种数据类型&#xff0c;元组…

portapack-h2使能hackrf

这两天弄了一块portapack扩展板 &#xff0c;可以用来脱机使能hackrf,简单的说&#xff0c;这是一块自带屏幕&#xff0c;预装gnuradio环境的单片机&#xff0c;通过GPIO插入hackrf,可以使能hackrf&#xff0c;脱机运行一些无线电测试程序。 购置的拓展先不用着急装扩展板&…

Web3 之路:构建开放、透明的数字生态系统

随着区块链技术的迅速发展&#xff0c;Web3正在成为数字世界的新引擎&#xff0c;重新定义着我们的生活和工作方式。在这个数字化的时代&#xff0c;我们目睹着一个全新的网络生态正在逐渐成形&#xff0c;其中开放性和透明性是其核心特征。让我们深入探讨&#xff0c;Web3如何…

一款适合程序员开发复杂系统的通用平台——JNPF 开发平台

在过去&#xff0c;很多开发工具更侧重代码编辑&#xff0c;针对数据库增删改查&#xff08;CRUD&#xff09;类的 Web 系统开发&#xff0c;在界面设计、前后端数据交互等环节主要还是靠写代码&#xff0c;效率比较低。目前很多所谓的低代码开发平台&#xff0c;大多数也都是基…