进程状态解析

目录

前言

一、进程概念

二、如何创建一个进程

 三、进程状态

3.1运行状态&休眠状态:

3.2前台与后台状态

3.3磁盘休眠状态

3.4暂停状态

3.5调试状态

3.6僵尸状态

3.7一种特殊的进程状态——孤儿进程

总结


前言

        在博主的上一篇文章中(点我查看),解释了有关冯诺依曼体系和操作系统的管理问题,当时在文末博主只解释了操作系统是以何种姿态来管理进程,但并没有解释什么是进程,本文博主就来解释一下有关进程的几个问题。


一、进程概念

        在介绍进程之间,我们需要了解这样一个事实:对于现代PC机来说,某一时刻往往可能有多个进程在运行,即使你开机之后什么也不干,操作系统和一些驱动程序也会强制运行。所以,此时操作系统作为第一个开机后“苏醒”的程序他如何来管理之后醒来的程序呢?在博主的上一篇文章中已经提到——“先描述,再组织”,在对进程进行描述时,我们知道单一的数据类型是难以将管理对象描述清楚的,所以操作系统使用了一个名为task_struct类型的结构体来对管理对象进行描述,这个结构体在操作系统上被叫做PCB(进程控制块)。它通常需要包含以下信息:

1.唯一标识符(pid)

2.状态:任务状态、退出码等

3.程序计数器:用来指认下一条需要执行的语句

4.内存指针:用来指向进程需要的数据、代码等

5.上下文数据:用来记录此时进程的执行状态

6.记账信息:用来记录进程消耗的时间信息,以保证时间片能正确轮转

7.I\O信息:包括显示的I\O请求、使用的文件列表信息、分配给进程的I\O设备等信息

8.其他信息 

        这里先对来说比较重要的就是操作系统是如何处理上下文数据的,我们要搞懂进程就要先解释以下这一点,我们首先要了解一下什么是上下文数据,比如说一个程序包括但不限与以下几种情况:程序正常运行结束、程序运行时间片到期程序被迫中断等,对于第二种情况,程序等待下一次被分配时间片时需要从上一次执行结束的地方继续执行。这时候就是上下文数据发挥作用的时候——当程序时间片到期时,CPU会将程序的执行状况从CPU的寄存器中拷贝回进程的PCB中,这些数据数据就是这个进程的上下文数据,等到下一次该进程再一次被分配时间片,上下文数据从PCB中拷入到CPU寄存器中,这样就可以接着从上一起程序离开的地方在接着执行。

        PCB中的其他信息将在后面一一说清,但是仅仅有PCB对于一个进程来说是远远不够的,因为PCB还需要进程的代码和数据。所以一个真正意义上的进程应该是这样的:

图1.1        进程的构成

二、如何创建一个进程

        那么在Linux中是如何创建一个进程的呢?

我们可以使用系统调用接口——fork(),来创建一个子进程:

 图2.1        fork接口文档

  我们可以使用系统调用接口来观察进程的pid信息,也可以使用shell命令观察,我们先来看一下getpid()接口的文档:

图2.2        getpid接口文档

 我们从文档中不难看出,getpid会返回该进程的ID信息,getppid则会返回父进程的ID信息,我们使用一下这两个接口,需要注意的是fork之后会有出现一个子进程,子进程和父进程共享代码,此时,也许你会有这样的疑惑为什么id这个变量既可以大于0又可以等于0,关于这一点,现在你只需要知道:fork之后子父进程共享代码,fork会返回两次数值,如果是子进程则返回0,如果是父进程则返回其ID值即可,关于为什么,不是本文讨论的话题,之后博主会再写一篇文章来解释这个现象。

图2.3        获取进程的ID信息

 三、进程状态

        在一些书本上,我们可以看到一些有关进程状态的图文,比如:

图3.1        有关进程状态的描述

但是这样的描述过于泛泛,我们来详细的看一下Linux中的进程状态:

1.R运行状态 (running)        :程序正在运行或处在运行队列中的状态

2.S睡眠状态 (sleeping)       :程序等待某些资源而陷入的等待状态 
3.D磁盘休眠 (disk sleep)    :又叫不可中断睡眠,这一状态的结果往往是等待I\O结束
4.T暂停状态 (stopped)        :可以通过发送SIGSTOP来实现,可用SIGCONT恢复
5.t调试状态 (tracing stop)   :可以被追溯的暂停状态

6.X执行结束 (dead)              :程序执行返回

7.Z僵尸状态 (zombie)          :因为父进程没有接受子进程返回码的子进程状态

 我们接下来一一介绍这几个状态:

3.1运行状态&休眠状态:

我们运行该程序:


  1 #include <stdio.h>
  2 #include <unistd.h>
  3 int main()
  4 {
  5     pid_t id=fork();
  6     while(1)
  7     {
  8         if(id>0)
  9         {
 10             printf("id:%d\n",id);
 11             printf("i am a father process! my    pid=%d                         myppid=%d\n",getpid(),getppid());
 12         }
 13         else if(id==0)                       
 14         {
 15             printf("i am a child process! myp    id=%d myppid=%d\n",getpid(),getppid());
 16         }
 17         sleep(1);
 18     }
 19 
 20     return 0;
 21 }

 并在命令窗口中使用一个监控脚本来观察这个程序的状态:

while :;do ps ajx |head -1 && ps axj | grep <可执行文件名> | grep -v grep ;sleep 1;done 

那么,你猜猜此时代码的运行状态应该是哪一种呢??

我们运行程序并打开监控查看:

图3.2        程序运行结果

你也许会很惊讶,你可能觉得疑惑——为什么不是运行状态而是休眠状态呢?要解释这个问题我们要先知道,运行状态是对CPU而言的,CPU的速度极快,实际上程序的时间大多消耗在了等待输出设备相应这一过程上了,所以此时是S状态,那我们更改一下代码,再看看结果。

 1 #include <stdio.h>
  2 #include <unistd.h>
  3 int main()
  4 {
  5     while(1);                                        
  6 
  7     return 0;
  8 }
图3.3        程序运行结果

则依次,主函数中只有一个循环,没有输入没有输出,不需要进行资源等待。此时就是一直处于运行态 。

3.2前台与后台状态

        你也许会好奇,为什么状态后面有一个+,这个其实就是表示此进程在前端运行,在前端运行的状态是会被默认的Ctrl+c操作阻止的,而没有+表示进程在后端运行,此时无法通过默认的Ctrl+c操作阻止。在Linux中我们可以在./执行程序名后面加上&符号就可让程序在后台运行:

图3.4        程序运行结果

3.3磁盘休眠状态

        由于磁盘休眠状态的发生前提过于刁钻,因此很难进行复现,这里简单解释一下:当计算机资源严重匮乏时,进程发出读写操作时,进程处于等待状态,然而此时由于资源紧张,操作系统会换出或终止一些正在等待的进程,则就可能导致了,进程控制读写操作时被强制终止,此时假设读写数据失败,返回进程时,磁盘缺发现进程终止,没有办法返回相应的信息。

 图3.5        磁盘休眠状态成因

         为了避免上述情况的发生,当数据十分重要时,我们可以将D状态给进程,这样就操作系统再清理一些等待资源的进程时就会越过这些进程。所以此时D状态的资源一般是在等待某些I\O的结束。因为磁盘休眠状态一般是发生在资源不足时,所以想要捕获这个状态是比较困难的。因为资过分紧张时带来的卡顿和死机都会给捕捉这一状态带来困难。

3.4暂停状态

        暂停状态我们可以使用SIGSTOP来实现一下,我们通过kill -l来查表发现SIGSTOP信号值为19

图3.6        kill信号表

运行该程序:

1 #include <stdio.h>
  2 #include <unistd.h>
  3 int main()
  4 {
  5     while(1)
  6     {
  7         printf("i am running!!\n");
  8         sleep(1);
  9     }                                     
 10 
 11     return 0;
 12 }
~
图3.7        运行结果

  

3.5调试状态

        调试状态就是程序再进行调试的状态,这一状态比较好理解就不在做演示了,读者可以自行使用gbd等工具进行实验。

3.6僵尸状态

        僵尸状态就是由于主进程没有接收子进程返回的信息而导致的状态。

运行该程序:

 #include <stdio.h>
  2 #include <unistd.h>
  3 #include <stdlib.h>
  4 int main()
  5 {
  6     pid_t id=fork();
  7 
  8     if(id==0)
  9     {
 10         sleep(5);
 11     }
 12     else
 13     {
 14         sleep(10);                        
 15         exit(0);
 16     }
 17 
 18     return 0;
 19 }
~
图3.8        运行结果

我们要考虑一下僵尸进程的危害:

我们这个程序显然不是实际场景中多进程的应用,一个进程被创建出来一定是要求完成一定的工作的,这个工作做的怎么样,好与不好,成功与失败,都要将结果返回给父进程来对特殊情况进行处理,Z状态存在的意义就是提醒进程需要被接收处理。倘若父进程不对子进程进行处理,那么子进程一直不退出,维护该进程的内核数据结构(PCB)也不会进行释放,进而导致了内存空间的泄漏问题。

3.7一种特殊的进程状态——孤儿进程

        当子进程再运行而父进程先于子进程退出,那么该子进程会由1号进程进行领养。

注意:进程于进程之间是有独立性的。这一点将在进程间的关系的时候详解,也就是说父进程的退出并不会影响子进程。

图3.9        孤儿进程

由1号进程进行接管孤儿进程也是出于对进程资源回收进行考虑。


总结

本文介绍了进程这一特殊的数据,在之后还会对这些数据之间的关系进行解释。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

上市公司-库存周转率、供应链效率明细数据集(2000-2022年)

01、数据介绍 库存周转率是衡量企业库存管理效率的关键指标之一&#xff0c;它反映了企业库存的流转速度。而供应链效率则体现了企业在整个供应链管理中的表现&#xff0c;包括采购、生产、物流等环节的协同和优化。 提高库存周转率和供应链效率是上市公司优化企业运营和管理…

蓝桥杯EDA常见电路原理图设计和分析

目录 前言 一、常见器件及其作用 二、原理图设计题目 1.蜂鸣器原理图 2.LCD背光控制电路 3.参考电压源 4.低通滤波器电路设计 5.5-3.3电源转换电路 6.3.3V-VDD_EXT电平转换电路 7.DS18B20原理图 8.供电输出控制接口电路 9.电源检测接口电路 10.USB转串口电路 三、…

TCP及IP协议

TCP协议的传输是可靠的&#xff0c;而UDP协议的传输“尽力而为” TCP传输可靠性———确认&#xff0c;重传&#xff0c;排序&#xff0c;流控。 流控&#xff1a;滑动窗口机制 TTL--- 数据包每经过一个路由器的转发&#xff0c;他的TTL值将减1&#xff0c;当一个数据包中的T…

网工常用工具——Xshell

今天给各位介绍一下&#xff0c;Xshell工具 Xshell是一款功能强大的终端模拟器&#xff0c;主要用于Windows操作系统&#xff0c;用于远程访问和管理服务器&#xff0c;允许用户通过SSH&#xff08;Secure Shell&#xff09;协议安全地连接到远程Linux/Unix服务器或其他支持SS…

FPGA+DDR+SERDES+USB3.0单向传输机方案,数据只能单向传输,避免反向攻击,确保系统安全

FPGADDRSERDESUSB3.0方案&#xff0c;设备包含发送端接收端&#xff0c;物料上采用光纤通讯&#xff0c;数据只能单向传输&#xff0c;避免反向攻击&#xff0c;确保系统安全 客户应用:高安全、高可靠性要求的场景 主要性能: 1.支持USB3.0传输&#xff0c;实测可达到350MB/s 2.…

OSI网络7层的功能介绍

目录 1.OSI功能介绍 2.SNA 3.X.25 1.OSI功能介绍 2.SNA SNA: IBM Systems Network Architecture)SNA是IBM公司开发的网络体系结构&#xff0c;在IBM公司的主机环境中得到广泛的应用。一般来说&#xff0c;SNA主要是IBM公司的大型机(ES/9000、S/390等)和中型机(AS/400)的主要…

智能绘画系统源码系统 后台自由设置会员套餐 带网站的安装包以及安装部署教程

在当今数字化与智能化快速发展的时代&#xff0c;艺术与技术正以前所未有的速度相互融合。为了满足广大绘画爱好者和专业艺术家的需求&#xff0c;我们精心打造了一款智能绘画系统源码系统。该系统不仅具备高度的智能化特性&#xff0c;还提供了丰富的后台管理功能&#xff0c;…

【Java一些注解知识】

RequestMapping RequestMapping是Spring框架中的一个注解&#xff0c;用于将HTTP请求映射到特定的处理方法上。通过使用RequestMapping注解&#xff0c;我们可以指定处理方法应该处理的URL路径和HTTP请求方法。 下面是一个简单的示例&#xff1a; 假设我们有一个UserControl…

VS code放大缩小

​ 放大 ctrl和一起按 缩小 ctrl和-一起按 上面是键盘组合方式&#xff0c;如果需要Ctrl滚轮实现代码的缩放&#xff0c;可以这样。 在文件-->首选项-->设置-->用户设置&#xff1a; 在搜索栏输入mouseWheelZoom 选中即可。 ​ 输入 mouseWheelZoom 进行搜素 特…

WPF之改变任务栏图标及预览

1&#xff0c;略缩图添加略缩按钮。 <Window.TaskbarItemInfo><TaskbarItemInfo x:Name"taskInfo" ProgressState"None" ProgressValue"0.6" ><TaskbarItemInfo.ThumbButtonInfos><ThumbButtonInfo x:Name"btiPlay&q…

2024年5月发布的SparkyLinux 8使用的是Debian 13 trixie 的更新源

2024年5月发布的SparkyLinux 8使用的是Debian 13 trixie 的更新源&#xff0c;然后我改了清华对应的更新源&#xff0c;更新成功。纯粹是测试&#xff0c;具体应以官网信息为主。

知名专业定制线缆知名智造品牌品牌推荐-精工电联:如何实现清扫机器人线缆产品的精益求精

在科技日新月异的今天&#xff0c;智能清扫机器人已经融入我们的日常生活。然而&#xff0c;其背后不可或缺的一部分&#xff0c;就是那些被称为机器人血管的精密线缆。精工电联作为高科技智能化产品及自动化设备专用连接线束和连接器配套服务商&#xff0c;致力于通过精益求精…

java中的oop(一)、概念

一、三大主线 &#xff08;非官方&#xff09; 成员&#xff1a;属性、方法、构造器、&#xff08;代码块&#xff0c;内部类&#xff09;&#xff1b; 特征&#xff1a;封装、继承、多态、&#xff08;抽象&#xff09;——三大特征&#xff1b; 关键字&#xff1a; this、…

Cmake编译源代码生成库文件以及使用

在项目实战中&#xff0c;通过模块化设计能够使整个工程更加简洁明了。简单的示例如下&#xff1a; 1、项目结构 project_folder/├── CMakeLists.txt├── src/│ ├── my_library.cpp│ └── my_library.h└── app/└── main.cpp2、CMakeList文件 # CMake …

Spark云计算平台Databricks使用,第一个Spark应用程序WordCount

1 上传文件 上传words.txt文件&#xff1a;Spark云计算平台Databricks使用&#xff0c;上传文件-CSDN博客 上传的文件的路径是/FileStore/tables/words.txt&#xff0c;保存在AWS的S3 hello world hello hadoop hello world hello databricks hadoop hive hbase yarn spark …

金蝶BI应收分析报表:关于应收,这样分析

这是一张出自奥威-金蝶BI方案的BI应收分析报表&#xff0c;是一张综合运用了筛选、内存计算等智能分析功能以及数据可视化图表打造而成的BI数据可视化分析报表&#xff0c;可以让企业运用决策层快速知道应收账款有多少&#xff1f;账龄如何&#xff1f;周转情况如何&#xff1f…

5.9号模拟前端面试10问

5.9号模拟前端面试10问 1.html语义化的理解 HTML语义化是指使用具有明确含义的HTML标签来描述内容&#xff0c;而不仅仅是使用<div>和<span>等通用容器标签。语义化的HTML代码更易于阅读和维护&#xff0c;同时也有助于搜索引擎优化&#xff08;SEO&#xff09;。…

前端基础知识-ES6扩展运算符(快速实现数组添加新元素、字符串转为数组、对象添加新属性)

前言&#xff1a; 扩展运算符又称为Rest运算符&#xff0c;可以实现数组、对象、字符串在语法层面上的展开&#xff0c;达到简化语法的目的&#xff0c;使得我们提高开发效率 主要用法&#xff1a; 在需要解构的变量前加三个点&#xff08;...xxx&#xff09; 具体示例&…

大数据毕业设计Python+Django地铁客流量预测 时间序列 深度学习 机器学习 人工智能 Python爬虫 计算机毕业设计

​ 博主介绍&#xff1a;全网粉丝100W,前互联网大厂软件研发、集结硕博英豪成立工作室。专注于计算机相关专业毕业设计项目实战6年之久&#xff0c;选择我们就是选择放心、选择安心毕业感兴趣的可以先收藏起来&#xff0c;点赞、关注不迷路 西安工程大学本科毕业设计&#xff…

Xamarin.Android项目网络串口助手怎么通过路由器跟PC网络串口连接

AndroidManifest.xml ![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/1ae7cd0d03c84343a62bccfd92e45d2c.png)