【Linux】进程状态|僵尸进程 |孤儿进程

news2024/9/21 0:45:08

索引

  • 运行状态:
  • 阻塞状态
  • 挂起状态
  • 看看Linux是怎么做的
    • 运行状态R
    • 睡眠状态S
    • 停止状态T
  • 两个特殊的进程:
    • 僵尸进程
    • 孤儿进程

在之前我们听过很多很多进程的状态,像是运行、新建、就绪、挂起、阻塞、等待、停止、挂机、死亡等等。

推荐阅读:通俗易懂帮你理清操作系统
接着上回说到了操作系统的先描述再组织,在操作系统内部用一个个的结构体来专门管理这些硬件,以及我们写好一个程序它要从磁盘加载到内存也是一个一个的PCB结构体来管理和维护的,
在这里插入图片描述
所谓进程状态就是进程内部的属性,这些属性都在task_struct内通过一些int类型的整数来表示例如:1代表运行状态、2代表停止状态、3代表挂起状态、4表示死亡状态等等。就绪和新建比较简单说的是这个进程PCB刚刚被创建好。

运行状态:

那么有这么多需要管理的硬件和进程,一般我们只有一个CPU怎么办呢?
其实CPU维护了一个进程队列,让这个进程在CPU上运行本质上是将该进程的task_struct结构体对象放入运行队列中!进程PCB在这个运行队列runqueue里,就是运行状态,不是这个进程正在CPU上运行,才是运行状态。

阻塞状态

我们知道CPU很快但是硬件很慢,而很多的进程又或多或少的要访问硬件(printf访问显示器、文件操作要访问磁盘等等),不能认为进程只会等待(占用)CPU资源,进程也可能随时随地要外设资源。但硬件也少,很多进程都要访问同一个硬件怎么办呢?其实每一个硬件对应的结构体里也有等待队列,当CPU的一个进程假如说(fwrite)需要访问磁盘的时候,而恰好这个时候别的进程也在访问,磁盘还没有被准备好去让fwrite去访问,那么这个fwrite对应的PCB结构体对象就只能从CPU的运行队列里剥离出来,去磁盘的等待队列里这个PCB结构体对象此时的状态,所以这种进程PCB结构体对象等待外设的状态就是所谓的阻塞状态。
在这里插入图片描述
等磁盘准备好了之后,操作系统需要把fwrite对应的PCB结构体对象的状态改为运行状态,然后再把它放到CPU的运行队列里,此时操作系统就不需要管了,接下来的工作由CPU去做了。

挂起状态

假如说由于下面三个进程因为外设没有准备好而处于阻塞状态,短期之内这些代码和数据就不会被执行,也就是不会被CPU调度,需要等待外设资源就绪才可以,那么加载进来的代码和数据依旧要占用内存,那么万一内存空间不够了怎么办?把代码和数据暂时保存回磁盘上,但他的内核数据结构PCB不大,还在内存中。此时就节省出来一部分空间再去运行别的程序了,所以一个进程暂时把它的代码和数据换出到磁盘的这种进程我们叫做该进程被挂起了,等什么时候这个进程可以被执行了,那么就可以再把这部分磁盘中的代码和数据再换回到内存中,把PCB再改为运行状态,进入CPU的运行队列里,再被CPU运行。把这种将进程的相关数据,加载或者保存到磁盘的行为叫做内存数据的换入换出。
在这里插入图片描述

所以所谓的进程不同的状态,本质是进程在不同的队列中,等待某种资源

看看Linux是怎么做的

其实Linux进程PCB是一个比较大的结构体,这里就把它内部的表示状态的内容节选下来。

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

  • R运行状态(running): 并不意味着进程一定在运行中,它表明进程要么是在运行中要么在运行队列里。

首先我们写一个这样的程序,查看现象:
在这里插入图片描述
上面这个死循环没有访问外设,运行起来查看他进程的状是R状态(运行状态)。
在这里插入图片描述


睡眠状态S

  • S睡眠状态(sleeping): 意味着进程在等待事件完成(这里的睡眠有时候也叫做可中断睡眠
    (interruptible sleep))。其实也就是Linux下的阻塞状态。

还是上面的那个程序我们把表示注释的//去掉,让它持续不断地打印1,就会发现这时候进程的状态就变成了S状态,因为printf本身要访问显示器是外设,是外设就比较慢,本身打印的话很快就打印了,但是等显示器就绪要花比较长的时间,这样的进程有99%的时间都是在等IO就绪,1%在执行打印代码,所以其实大部分访问外设的进程的状态基本都是S状态
在这里插入图片描述


停止状态T

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

在命令行输入kill -l,就可以看到kill下其实是有很多选项的
在这里插入图片描述
其中第19个选项,找到对应的pid号输入kill -19 pid号或者ctrl+z都是使当前进程停下来的方法。
在这里插入图片描述

查看进程的状态的时候就发现它是T状态。
然后再使用kill -18 pid号可以再让这个进程运行起来,
在这里插入图片描述
但是此时无法再被暂停的,在命令行输入命令也无济于事,细心的小伙伴可以发现虽然暂停前和暂停后都是S状态,但之前的S后面跟另一个‘+’,后面那个却没有’+',那么当前没有‘+’的状态就是后台进程,有‘+’的就是前台进程。这样的后台进程只能用kill -9 pid号来杀掉当前进程。
在这里插入图片描述
至于上面说到的挂起状态,可以看到似乎并没有一种叫做挂起的状态,那是因为操作系统认为挂起状态不需要暴露给用户,用户只需要知道进程在不在运行、是不是休眠、是不是暂停、是不是退出了也就可以了,就算让用户知道也没有任何意义和作用,所以在这么多状态里就没有一种叫做挂起的状态。

其他状态:


  • D磁盘休眠状态(Disk sleep)有时候也叫不可中断睡眠状态(uninterruptible sleep),在这个状态的进程通常会等待IO的结束。D状态也叫深度睡眠状态,相比于上面的S状态,D状态是无法被kill -19 pid号或者ctrl+z来暂停的,在该状态的进程无法被操作系统杀掉,只能通过断电或者进程自己醒来来解决。
  • t (tracing stop)状态举一个例子来说就是当我们用gdb调试起来的时候,此时他的状态就是t状态。

从上面你可以看出来那么R就是运行状态、S是一种浅度睡眠其实它就是一种阻塞状态、D也是一种阻塞状态,t、T它都是阻塞状态只不过这些阻塞状态是为了满足于不同的应用场景。

  • 僵尸状态Z:进程退出的时候,不能立即释放该进程对应的资源!需要保存一段时间,让父进程或者0S来进行读取!这一段时间内这个进程的状态就叫僵尸状态。

  • X死亡状态(dead):这个状态只是一个返回状态,你不会在任务列表里看到这个状态,是把进程PCB回收之后的状态。也就是说一个进程正常退出的时候是先是Z状态,然后是X状态


下面这幅图来描述这几个状态之间的关系。
在这里插入图片描述

两个特殊的进程:

僵尸进程

当一个进程运行完毕时,它所占用的内存资源和执行的退出状态需要被它的父进程回收。如果父进程没有回收这些东西,这个进程就是僵尸进程。如果父进程长时间不回收进程数据,那么这个进程将长期处于僵尸状态,其PCB和代码依旧存储在内存中,占用空间但是不会被执行。

我们写一个代码:
在这里插入图片描述

父子进程同时运行,此时杀掉子进程,子进程就停止运行了,但此时父进程还在忙着执行自己的代码,也就回收不了子进程的空间与返回状态,所以此时子进程就处于僵尸状态了,注意下面大写Z。
在这里插入图片描述

对于僵尸进程的理解:

  • 进程的占用内存与退出结果对操作系统而言十分重要,不管成功还是失败子进程都要告诉它的父进程自己的任务完成得怎么样了。但是如果父进程一直不读取这些数据,那子进程既不执行也占用空间,也就会一直处于Z状态。
  • 只要进程没有死亡进程基本信息就不会被清除,所以保存数据的PCB就会继续被操作系统维护。
  • 如果一个父进程创建了很多子进程,子进程执行完毕后就是不回收,进程的PCB和执行完毕或者因错误终止的代码就会一直储存在内存中,就会造成内存资源的浪费。这很类似于我们C/C++中的内存泄漏问题

孤儿进程

孤儿进程正好反过来了是指父进程先于子进程退出,父进程死亡,子进程就没有了父进程,这时的子进程就会变成孤儿进程。但是父进程的死亡不代表孤儿进程就没有了父进程,每一个孤儿进程都会被一号进程也就是操作系统领养。这种被领养的进程就叫孤儿进程。

用上面相同的代码,这次我们干掉父进程,同时查看进程状态。 我们可以发现子进程的父进程pid变为了1,也就是说子进程会被1号进程收养,并在子进程执行完毕后回收所对应的资源。
在这里插入图片描述
同时我们也可以看到,子进程状态从之前的S+变为S,也就是说从这个被收养的子进程变为了一个后台进程了,也就是不能用ctrl+z暂停,只能用kill -9来杀掉这个进程。

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

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

相关文章

http协议之digest(摘要)认证,详细讲解并附Java SpringBoot源码

目录 1.digest认证是什么? 2.digest认证过程 3.digest认证参数详解 4.基于SpringBoot实现digest认证 5.digest认证演示 6.digest认证完整项目 7.参考博客 1.digest认证是什么? HTTP通讯采用人类可阅读的文本格式进行数据通讯,其内容非…

Android入门第40天-Android中的Service(SimpleStartService)

简介 博文总阅读量已经突破了300万,给自己加油打CALL。 从今天开始,之前39天的Android如果每一篇只有30分钟就能读完和掌握那么从今天开始越往后会越复杂。因为我们的Android教程开始进入“中级”难度了。特别是Service,这个Service我要分成…

java面向对象的三大特性之封装和继承(配视频讲解)

🍅程序员小王的博客:程序员小王的博客 🍅程序员小王的资源博客:http://wanghj.online/ 🍅 欢迎点赞 👍 收藏 ⭐留言 📝 🍅 如有编辑错误联系作者,如果有比较好的文章欢迎…

JMeter入门教程(13) --事务

文章目录1.任务背景2.任务目标3.任务实操3.1.1 事务控制器3.2.2循环控制器1.任务背景 JMeter中的事务是通过事务控制器实现的。,为了衡量服务器对某一个或一系列操作处理的响应时间,需要定义事务。下面我们详细介绍在JMeter中如何使用事务 2.任务目标 …

基于JSP的网络教学平台的设计与实现

目 录 摘 要 I Abstract II 一、 引言 1 (一)项目开发的背景 1 (二)项目开发的意义 1 二、可行性分析及总体设计原则 3 (一)可行性分析 3 1.技术可行性 3 2.经济可行性 3 3&#xff…

MATLAB算法实战应用案例精讲-【图像处理】目标检测(附实战案例及代码实现)

前言 目标检测,也叫目标提取,是一种基于目标几何和统计特征的图像分割。它将目标的分割和识别合二为一,其准确性和实时性是整个系统的一项重要能力。尤其是在复杂场景中,需要对多个目标进行实时处理时,目标自动提取和识别就显得特别重要。 随着计算机技术的发展和计算机视…

Servlet —— Tomcat, 初学 Servlet 程序

JavaEE传送门JavaEE HTTP —— HTTP 响应详解, 构造 HTTP 请求 HTTPS —— HTTPS的加密方式 目录TomcatServlethello world创建项目引入 Servlet 依赖创建目录结构编写代码doGet打包程序部署程序验证程序Tomcat Tomcat 是一个 HTTP 服务器 HTTP 客户端, 就是大家平时用到的浏…

大数据hadoop_HDFS概述(1)

文章目录1. HDFS概述1.1 HDFS背景1.2 定义2. HDFS优缺点2.1 优点2.2 缺点3. HDFS架构4. HDFS文件块大小1. HDFS概述 1.1 HDFS背景 面对今天的互联网公司,每天都会有上亿次的用户访问量,用户每进行一次操作,都会产生数据,面对传统…

Android入门第41天-Android中的Service(bindService)

介绍 在前一天我们介绍了Android中有两种启动Service的方法。并擅述了startService和bindService的区别。同时我们着重讲了startService。 因此今天我们就来讲bindService。bindService大家可以认为它是和Android的一个共生体。即这个service所属的activity如果消亡那么bindS…

Docker涉及的Linux命名空间、CGroups

概述 Linux的NameSpace介绍 很多编程语言都包含了命名空间的概念,我们可以认为命名空间是一种封装,封装本身实现了代码的隔离。在操作系统中命名空间提供的是系统资源的隔离,其中系统资源包括了:进程、网络、文件系统…实际上li…

《模拟电子技术》半导体原理部分笔记

《模拟电子技术》笔记绪论第一章 常用半导体器件第二章 基本放大电路绪论 有的人把三极管的出现作为电子技术工业革命的开始标志学习架构:半导体器件(二极管、三极管、场效应晶体管)、基于上述管的放大电路、集成运算放大器、放大电路的频率…

第11章 初识IdentityServer4

1 构建IdentityServer4 服务 1.1 通过配置类配置类(Config)实例化IdentityServer4中间件 using IdentityServer4.Models; namespace BuilderServer { /// <summary> /// 【配置--类】 /// <remarks> /// 摘要&#xff1a; /// 通过该中类的方法成员&#xff…

如何给firefox和google chrome鼠标手势

背景 已经习惯了有鼠标手势&#xff0c;因为一天到晚都在浏览器上查询资料&#xff0c;所以必须把这个鼠标手势设置好。 firefox 搜索Foxy Gestures然后安装 google chrome crxMouse Chrome 点击google浏览器上的扩展程序图标&#xff0c;然后点击管理扩展程序&#xff1a…

游泳耳机哪个牌子好、分享几款游泳听音乐最好的耳机推荐

如今,水上运动爱好者越来越多了,无论是游泳,还是冲浪早已成为了我们很多人经常参加的运动项目。不过他们都抱怨过类似的问题——可以在水上运动中使用的无线耳机实在是太少了。防水性能达不到可游泳级别,不带内存需要配备手机使用,这些都是造成耳机无法在水上使用的原因。今天小…

【matplotlib】1-使用函数绘制图表

文章目录使用函数绘制图表1.绘制matplotlib图表组成元素的主要函数2.准备数据3.函数用法3.1函数plot()--展现变量的趋势变化3.2函数scatter()--寻找变量之间的关系3.3函数xlim()--设置x轴的数值显示范围3.4函数xlabel()--设置x轴的标签文本3.5 函数grid()--绘制刻度线的网格线3…

Kong(三)Konga UI安装和使用

一 konga 的github地址 konga安装参考 ① Kong 可视化UI 选择 官方kong-dashboard 1&#xff09;收费&#xff1a;当前kong的社区版是没有dashboard的,但是付费的企业版是有带的2&#xff09;kong-dashboard最新版本v3.6.0,只支持到kongv0.14.x,对于更高的kong版本,功能支…

SpringBoot整合RabbitMQ,实现单机抢票系统

MQ全称为Message Queue, 消息队列&#xff08;MQ&#xff09;是一种应用程序对应用程序的通信方法。MQ是消费-生产者模型的一个典型的代表&#xff0c;一端往消息队列中不断写入消息&#xff0c;而另一端则可以读取队列中的消息。 消息中间件最主要的作用是解耦&#xff0c;中间…

C与C++中的常用符号与标点用法详解及实例

C与C中的常用符号与标点符号有&#xff1a;“”、“-”、“*”、 “/”、“%”、“&”、“\”、“|”、“~”、“^”、“&”、“|”、“&#xff01;”、“>”、“<”、""、“#”、“&#xff1f;”、“&#xff0c;”、“.”、“&#xff1a;”、单引…

d3rlpy离线强化学习算法库安装及使用

GitHub - takuseno/d3rlpy: An offline deep reinforcement learning library d3rlpy&#xff0c;离线强化学习算法库 我装在windows下用anaconda&#xff0c;按照官网教程 conda install -c conda-forge d3rlpy 第一次安装报错CondaSSLError: OpenSSL appears to be unavaila…

Kubernetes的service详解

文章目录Service介绍Service类型Service使用ClusterIP类型的ServiceHeadLiness类型的ServiceNodePort类型的ServiceLoadBalancer类型的ServiceExternalName类型的ServiceIngress介绍Service介绍 在kubernetes中&#xff0c;pod是应用程序的载体&#xff0c;我们可以通过pod的i…