linux_进程状态

目录

一. 概念铺设

状态是什么?

传统操作系统的状态转换图

二. 传统操作系统状态

1. 运行

2. 阻塞

3. 挂起

三. linux 中的进程状态

1. 总体介绍

2. R

3. S

4. D

kill -9

D vs S

5. T

kill 

T vs S

6. Z

什么是僵尸状态?

僵尸进程的危害

7. D

父进程的作用

8. 孤儿进程


一. 概念铺设

状态是什么?

状态就是一个用来描述该进程当前正在做什么。

传统的操作系统的状态有:

  • 运行
  • 阻塞
  • 挂起

传统操作系统的状态转换图

二. 传统操作系统状态

1. 运行

我们知道,在我们现在的操作系统中有许多进程(我们现在的系统多数都是时间片轮转调用的),但是一般的电脑只有一个 CPU ,而进程要运行必须要使用 CPU ,所以在同一时刻肯定是只有一个进程占用CPU资源,但是在用户的观感上好像我们计算机上的进程都是同时在运行的。

实际上,在操作系统中有一个队列叫做运行队列,而在运行队列中的进程就是运行态,并不是说只有当进程在运行的那一刻才是运行状态

所以运行状态就是在运行队列里面等待的进程就是运行状态,对于时间片轮状的操作系统来说,每一个进程每一次只执行特定长的时间,如果执行没有结束就继续到等待队列的后面继续排队,如果执行完毕,那么就从等待队列中删掉。

2. 阻塞

阻塞也是传统的操作系统书中的一个状态,而阻塞就是当一个进程需要某种外设资源的时候的状态。

比如说,当我们使用C语言进行 scanf 的时候,或者使用 C++ cin 的时候,此时就是阻塞状态,就是该进程需要等待键盘资源输入,或者也有就是向显示器上打印等...

3. 挂起

挂起状态时常不会用到的,挂起状态就是当操作系统内资源不足的时候,当一个进程不运行,但是占着操作系统资源,然后此时操作系统还时资源紧张,那么操作系统会将该进程的代码和数据换到磁盘里面,当该进程运行的时候才会将该进程的代码和数据继续换入到内存中,所以挂起就是一个进程的PCB在内存中,但时它的代码和数据被换到磁盘里面就是挂起状态。

三. linux 中的进程状态

1. 总体介绍

  • 运行 (R):进程正在运行或已经准备好运行。
  • 休眠 (S):进程处于休眠状态,等待某个事件的发生,如I/O操作或信号。
  • 中断 (D):进程处于不可中断的睡眠状态,通常是等待设备或资源,如磁盘I/O。
  • 僵尸 (Z):进程已经终止,但是其父进程还未收到终止信号或未进行处理,进程存在但没有参与运行。
  • 停止 (T):进程被暂停或停止,通常是由于收到停止信号,如Ctrl+Z。
  • 僵尸 (X):进程已经终止,但是其父进程已经终止或退出,僵尸进程被init进程(PID为1)接管。

 

2. R

在 linux 中的 R  状态就是对应的是运行状态。

那么下面就写一个代码来查看该进程的状态。

int main()
{
  while(1)
  {
    printf("hello world\n");
    sleep(1);
  }
  return 0;
}

我们还是使用 ps 来查看进程的状态。

[lxy@hecs-165234 linux3]$ ps axj | head -1 && ps axj | grep proc
 PPID   PID  PGID   SID TTY      TPGID STAT   UID   TIME COMMAND
 6468  8145  8145  6468 pts/1     8145 S+    1000   0:00 ./proc

这里看到,我们查到该进程的状态是 S,为什么呢?因为我们之前说过,我们的进程一般在runQueue里面才算是执行,那么当我们打印的时候我们需要等待外设(显示器),然后由于外设比较慢,所以大多数时间都是再等待,所以我们就看到的是S状态,并不是R。

所以这时候我们可以去掉打印,我们一直死循环,我们就可以看到 R 状态了。

int main()
{
  while(1);
  return 0;
}
 PPID   PID  PGID   SID TTY      TPGID STAT   UID   TIME COMMAND
 6468  8453  8453  6468 pts/1     8453 R+    1000   0:02 ./proc

这时候查看到的就是 R 状态,这里为什么是R+ 呢? 这里的+表示在前台运行,也就是在 bash 前端运行。

3. S

s状态其实我们刚才已经看到了,就是打印的时候我们一直看到的是S状态,这是因为我们在等待显示器资源。

4. D

D状态其实也就是睡眠状态,那么和S状态有什么不同呢?

其中S是浅度睡眠,而D是深度睡眠。

浅度睡眠是可以被杀死的,而深度睡眠不能被杀死。

这里穿插一条知识。

kill -9

kill 是信号,kill -9 是一条杀死进程的信号,后面加进程PID 就可以向进程发送该信号,而D状态就是不能被杀死。

D vs S

D状态和S状态的区别?

场景:

当一个进程向磁盘写入很大的数据的时候,该进程在等待,那么这个时候如果操作系统直接杀死该进程,那么向磁盘中写入数据后失败或者成功,磁盘都会向该进程反馈,但是此时操作系统杀死了该进程,如果写入失败,导致磁盘数据被丢失,那么后果还是很严重的,所以在进程向磁盘写入数据的时候,进程等待磁盘返回的时候,此时的进程就是处于D状态也就是胜读睡眠状态,这时候的进程不能被杀死。

由于这个状态不好演示,所以这里也就不演示了。

5. T

T状态就是停止状态,就是该进程停止了,我们也可以通过信号来控制。

[lxy@hecs-165234 linux3]$ kill -l
 1) SIGHUP	 2) SIGINT	 3) SIGQUIT	 4) SIGILL	 5) SIGTRAP
 6) SIGABRT	 7) SIGBUS	 8) SIGFPE	 9) SIGKILL	10) SIGUSR1
11) SIGSEGV	12) SIGUSR2	13) SIGPIPE	14) SIGALRM	15) SIGTERM
16) SIGSTKFLT	17) SIGCHLD	18) SIGCONT	19) SIGSTOP	20) SIGTSTP
21) SIGTTIN	22) SIGTTOU	23) SIGURG	24) SIGXCPU	25) SIGXFSZ
26) SIGVTALRM	27) SIGPROF	28) SIGWINCH	29) SIGIO	30) SIGPWR
31) SIGSYS	34) SIGRTMIN	35) SIGRTMIN+1	36) SIGRTMIN+2	37) SIGRTMIN+3
38) SIGRTMIN+4	39) SIGRTMIN+5	40) SIGRTMIN+6	41) SIGRTMIN+7	42) SIGRTMIN+8
43) SIGRTMIN+9	44) SIGRTMIN+10	45) SIGRTMIN+11	46) SIGRTMIN+12	47) SIGRTMIN+13
48) SIGRTMIN+14	49) SIGRTMIN+15	50) SIGRTMAX-14	51) SIGRTMAX-13	52) SIGRTMAX-12
53) SIGRTMAX-11	54) SIGRTMAX-10	55) SIGRTMAX-9	56) SIGRTMAX-8	57) SIGRTMAX-7
58) SIGRTMAX-6	59) SIGRTMAX-5	60) SIGRTMAX-4	61) SIGRTMAX-3	62) SIGRTMAX-2
63) SIGRTMAX-1	64) SIGRTMAX	

[lxy@hecs-165234 linux3]$ ps axj | grep proc
 6468  8501  8501  6468 pts/1     8501 R+    1000   0:26 ./proc
 6180  8503  8502  6180 pts/0     8502 R+    1000   0:00 grep --color=auto proc
[lxy@hecs-165234 linux3]$ kill -19 8501

kill 

kill -l 是查看信号的命令,19 号信号是一个告诉进程停止的信号,所以我们向我们的进程发送19号信号,然后我们在继续查看该进程的状态。

[lxy@hecs-165234 linux3]$ ps axj | grep proc
 6468  8501  8501  6468 pts/1     8504 T     1000   0:54 ./proc

此时就是T状态,那么我们怎么恢复呢? 我们使用18号信号,这里也就不演示了,但是这里说明一下,如果从18号信号恢复过来的话,就变成后台运行了,所以我们 ctrl + c就干不掉了,我们需要使用 kill -9 来杀死它。

T vs S

T和S状态的区别,我们这里感觉T 和 S没有什么区别,但是还是有区别的,S状态就是进程在等待外设资源的一种状态,而T是可能在等待资源,但是也不一定是在等待资源。

6. Z

Z 是僵尸状态。

什么是僵尸状态?

场景:国外发生的一起凶杀案,现在有人看到并且报警,此时警察过来首先先检验受害人是否死亡,或者死亡原因,当检验完毕后,并且警方处理完了所有的事情然后等待受害者家属来为受害者进行后续操作,在受害者家属来之前,受害者就是属于僵尸状态。

所以当一个进程死亡后,如果关心它的进程(也就是父进程)没有来接收子进程的返回的数据等,那么此时的子进程就是僵尸状态。

我们下面让子进程运行5秒后退出,然后父进程持续运行,我们来观察此时的状态。

int main()
{
  pid_t id = fork();

  if(id == 0)
  {
    int count =  5;
    while(count--)
    {
      printf("I am a child... PID: %d, PPID: %d, time: %d\n", getpid(), getppid(), count);
      sleep(1);
    }
  }
  else 
  {
    while(1)
    {
      printf("I am a father... PID: %d, PPID: %d\n", getpid(), getppid());
      sleep(1);
    }
  return 0;;
}

我们此时在写一个监控脚本来看这里的变化。

[lxy@hecs-165234 linux3]$ while : ; do ps axj | head -1 && ps axj | grep proc | grep -v grep; sleep 1; done

这时候我们这个脚本就会查看 proc 的PCB

[lxy@hecs-165234 linux4]$ ./proc 
I am a father... PID: 9542, PPID: 6468
I am a child... PID: 9543, PPID: 9542, time: 4
I am a father... PID: 9542, PPID: 6468
I am a child... PID: 9543, PPID: 9542, time: 3
I am a father... PID: 9542, PPID: 6468
I am a child... PID: 9543, PPID: 9542, time: 2
I am a father... PID: 9542, PPID: 6468
I am a child... PID: 9543, PPID: 9542, time: 1
I am a father... PID: 9542, PPID: 6468
I am a child... PID: 9543, PPID: 9542, time: 0
I am a father... PID: 9542, PPID: 6468
I am a father... PID: 9542, PPID: 6468
 6468  9542  9542  6468 pts/1     9542 S+    1000   0:00 ./proc
 9542  9543  9542  6468 pts/1     9542 S+    1000   0:00 ./proc
 PPID   PID  PGID   SID TTY      TPGID STAT   UID   TIME COMMAND
 6468  9542  9542  6468 pts/1     9542 S+    1000   0:00 ./proc
 9542  9543  9542  6468 pts/1     9542 S+    1000   0:00 ./proc
 PPID   PID  PGID   SID TTY      TPGID STAT   UID   TIME COMMAND
 6468  9542  9542  6468 pts/1     9542 S+    1000   0:00 ./proc
 9542  9543  9542  6468 pts/1     9542 S+    1000   0:00 ./proc
 PPID   PID  PGID   SID TTY      TPGID STAT   UID   TIME COMMAND
 6468  9542  9542  6468 pts/1     9542 S+    1000   0:00 ./proc
 9542  9543  9542  6468 pts/1     9542 S+    1000   0:00 ./proc
 PPID   PID  PGID   SID TTY      TPGID STAT   UID   TIME COMMAND
 6468  9542  9542  6468 pts/1     9542 S+    1000   0:00 ./proc
 9542  9543  9542  6468 pts/1     9542 S+    1000   0:00 ./proc
 PPID   PID  PGID   SID TTY      TPGID STAT   UID   TIME COMMAND
 6468  9542  9542  6468 pts/1     9542 S+    1000   0:00 ./proc
 9542  9543  9542  6468 pts/1     9542 Z+    1000   0:00 [proc] <defunct>

这里看到,此时我们最后子进程退出了,然后父进程还在运行,这是子进程就是Z僵尸状态。

僵尸进程的危害

那么进程一直僵尸会怎么样呢?

  • 浪费系统资源:每个进程都需要一定的系统资源,如内存和描述符。当大量的僵尸进程存在时,会占用过多的系统资源,影响系统的正常运行和其他进程的执行效率。
  • 产生内核问题:僵尸进程过多可能会导致系统的内核出现问题。尽管现代操作系统可以处理一定数量的僵尸进程,但如果没有及时清理,可能会导致内核资源不足或崩溃。
  • 父进程遭受拖累:僵尸进程的父进程可能会受到影响。如果父进程没有正确处理僵尸进程,它们的退出状态将一直保存在内核中,导致父进程的进程表中存在大量的僵尸进程。

虽然僵尸进程本身不会对系统造成直接的危害,但当过多的僵尸进程堆积时,会消耗系统资源并可能导致系统不稳定。因此,及时清理僵尸进程非常重要。一般来说,操作系统的init进程会负责清理僵尸进程,当子进程退出后,init进程会接管并回收僵尸进程的资源。

7. D

D状态就是死亡 dead 状态,也就是退出状态,而在每一个D状态之前都会有一段时间是Z状态的,因为这里的父进程要回收子进程。

父进程的作用

所以这里就体现了为什么要有父进程,因为父进程要对退出的子进程进行回收。

8. 孤儿进程

孤儿进程,见名知意,就是没有父进程的进程,我们下面演示一下。

我们写一个代码,让子进程一直运行,让父进程提前退出,然后我们打开监控脚本看一下。

int main()
{
  pid_t id = fork();

  if(id == 0)
  {
    while(1)
    {
      printf("I am a child... PID: %d, PPID: %d\n", getpid(), getppid());
      sleep(1);
    }
  }
  else 
  {
    int count = 5;
    while(count--)
    {
      printf("I am a father... PID: %d, PPID: %d\n", getpid(), getppid());
      sleep(1);
    }
  }
  return 0;;
}

运行,打开监控脚本查看。

[lxy@hecs-165234 linux4]$ ./proc 
I am a father... PID: 9780, PPID: 6468
I am a child... PID: 9781, PPID: 9780
I am a father... PID: 9780, PPID: 6468
I am a child... PID: 9781, PPID: 9780
I am a father... PID: 9780, PPID: 6468
I am a child... PID: 9781, PPID: 9780
I am a father... PID: 9780, PPID: 6468
I am a child... PID: 9781, PPID: 9780
I am a father... PID: 9780, PPID: 6468
I am a child... PID: 9781, PPID: 9780
I am a child... PID: 9781, PPID: 1
 PPID   PID  PGID   SID TTY      TPGID STAT   UID   TIME COMMAND
 6468  9780  9780  6468 pts/1     9780 S+    1000   0:00 ./proc
 9780  9781  9780  6468 pts/1     9780 S+    1000   0:00 ./proc
 PPID   PID  PGID   SID TTY      TPGID STAT   UID   TIME COMMAND
 6468  9780  9780  6468 pts/1     9780 S+    1000   0:00 ./proc
 9780  9781  9780  6468 pts/1     9780 S+    1000   0:00 ./proc
 PPID   PID  PGID   SID TTY      TPGID STAT   UID   TIME COMMAND
    1  9781  9780  6468 pts/1     6468 S     1000   0:00 ./proc
 PPID   PID  PGID   SID TTY      TPGID STAT   UID   TIME COMMAND
    1  9781  9780  6468 pts/1     6468 S     1000   0:00 ./proc

这里还是只展示部分。

我们看到我们的父进程退出了,然后子进程的PPID变成了1,那么1是什么呢?

[lxy@hecs-165234 linux3]$ ps axj | head -1 && ps axj | grep 1
 PPID   PID  PGID   SID TTY      TPGID STAT   UID   TIME COMMAND
    0     1     1     1 ?           -1 Ss       0  26:38 /usr/lib/systemd/systemd --system --deserialize 23

这里看到我们的1就是system 所以我们的子进程就被系统领养,此时我们的子进程的退出就由操作系统回收了。

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

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

相关文章

详解Mybatis之自动映射 自定义映射问题

编译软件&#xff1a;IntelliJ IDEA 2019.2.4 x64 操作系统&#xff1a;win10 x64 位 家庭版 Maven版本&#xff1a;apache-maven-3.6.3 Mybatis版本&#xff1a;3.5.6 文章目录 一、Mybatis中的自动映射是什么&#xff1f;二、Mybatis中的自定义映射是什么&#xff1f;三、为什…

Spring的创建及使用

文章目录 什么是SpringSpring项目的创建存储Bean对象读取Bean对象getBean()方法 更简单的读取和存储对象的方式路径配置使用类注解存储Bean对象关于五大类注解使用方法注解Bean存储对象Bean重命名 Bean对象的读取 使用Resource注入对象Resource VS Autowired同一类型多个bean对…

租赁固定资产管理

智能租赁资产管理系统可以为企业单位提供RFID资产管理系统。移动APP资产管理&#xff0c;准确总结易损耗品和固定资金&#xff0c;从入库到仓库库存实时跟踪&#xff0c;控制出库和入库的全过程。同时&#xff0c;备件和耗材与所属资产设备有关&#xff0c;便于备件的申请和管理…

express学习笔记3 - 三大件

便于统一管理router&#xff0c;创建 router 文件夹&#xff0c;创建 router/index.js&#xff1a; const express require(express)// 注册路由 const router express.Router() router.get(/,function(req,res){res.send(让我们开始express之旅) }) /*** 集中处理404请求的…

【雕爷学编程】MicroPython动手做(27)——物联网之掌控板小程序3

知识点&#xff1a;什么是掌控板&#xff1f; 掌控板是一块普及STEAM创客教育、人工智能教育、机器人编程教育的开源智能硬件。它集成ESP-32高性能双核芯片&#xff0c;支持WiFi和蓝牙双模通信&#xff0c;可作为物联网节点&#xff0c;实现物联网应用。同时掌控板上集成了OLED…

python与深度学习(十二):CNN和猫狗大战二

目录 1. 说明2. 猫狗大战的CNN模型测试2.1 导入相关库2.2 加载模型2.3 设置保存图片的路径2.4 加载图片2.5 图片预处理2.6 对图片进行预测2.7 显示图片 3. 完整代码和显示结果4. 多张图片进行测试的完整代码以及结果 1. 说明 本篇文章是对上篇文章猫狗大战训练的模型进行测试。…

NIDEC COMPONENTS尼得科科宝滑动型DIP开关各系列介绍

今天AMEYA360对尼得科科宝电子滑动型DIP开关各系列参数进行详细介绍&#xff0c;方便大家选择适合自己的型号。 系列一、滑动型DIP开关 CVS 针脚数&#xff1a;1, 2, 3, 4, 8 安装类型&#xff1a;表面贴装&#xff0c;通孔 可水洗&#xff1a;无 端子类型&#xff1a;PC引脚(只…

PostgreSql 进程及内存结构

一、进程及内存架构 PostgreSQL 数据库运行时&#xff0c;使用如下命令可查询数据库进程&#xff0c;正对应上述结构图。 [postgreslocalhost ~]$ ps -ef|grep post postgres 8649 1 0 15:05 ? 00:00:00 /app/pg13/bin/postgres -D /data/pg13/data postgres …

一文掌握linux系统管理命令

欢迎关注博主 Mindtechnist 或加入【Linux C/C/Python社区】一起学习和分享Linux、C、C、Python、Matlab&#xff0c;机器人运动控制、多机器人协作&#xff0c;智能优化算法&#xff0c;滤波估计、多传感器信息融合&#xff0c;机器学习&#xff0c;人工智能等相关领域的知识和…

百度:文心千帆 网页搭建和示例测评

文章目录 官方文档代码示例token获取流式回答官网完整示例 制作一个网页端 官方文档 https://cloud.baidu.com/doc/WENXINWORKSHOP/s/flfmc9do2按照这个操作进行创建一个应用&#xff1a; 代码示例 token获取 # 填充API Key与Secret Key import requests import jsondef ma…

earth靶机详解

earth靶机复盘 靶场下载地址&#xff1a;https://download.vulnhub.com/theplanets/Earth.ova 这个靶场还是非常有意思的&#xff0c;值得去打一下。 我们对拿到的ip进行一个单独全面的扫描&#xff0c;发现有两个DNS解析。 就把这两条解析添加到hosts文件中去&#xff0c;要…

Java maven的下载解压配置(保姆级教学)

mamen基本概念 Maven项目对象模型(POM)&#xff0c;可以通过一小段描述信息来管理项目的构建&#xff0c;报告和文档的项目管理工具软件。 Maven 除了以程序构建能力为特色之外&#xff0c;还提供高级项目管理工具。由于 Maven 的缺省构建规则有较高的可重用性&#xff0c;所以…

分布式异步任务处理组件(五)

节点上线和下线的逻辑-- 节点下线分为两种--心跳失败主动或被动和主节点断开连接&#xff0c;但是节点本身没有发生重启&#xff1b;第二种就是节点宕机重启--其实这两中情况下处理逻辑都是一样的&#xff0c;只是节点本身如果还能消费到kafka的时候可以继续执行任务但是不能从…

Web-7-深入理解Cookie与Session:实现用户跟踪和数据存储

深入理解Cookie与Session&#xff1a;实现用户跟踪和数据存储 今日目标 1.掌握客户端会话跟踪技术Cookie 2.掌握服务端会话跟踪技术Sesssion 1.会话跟踪技术介绍 会话&#xff1a;用户打开浏览器&#xff0c;访问web服务器的资源&#xff0c;会话建立&#xff0c;直到有一方断…

[SSM]GoF之代理模式

目录 十四、GoF之代理模式 14.1对代理模式的理解 14.2静态代理 14.3动态代理 14.3.1JDK动态代理 14.3.2CGLIB动态代理 十四、GoF之代理模式 14.1对代理模式的理解 场景&#xff1a;拍电影的时候&#xff0c;替身演员去代理演员完成表演。这就是一个代理模式。 演员为什…

数控机床主轴品牌选择及选型,如何维护和保养?

数控机床主轴品牌选择及选型&#xff0c;如何维护和保养&#xff1f; 数控机床是一种高精度、高效率、高自动化的机床。其中&#xff0c;主轴是数控机床的核心部件&#xff0c;承担着转动工件、切削加工的任务&#xff0c;决定了加工的转速、切削力度和加工效率。因此&#xff…

解决多线程环境下单例模式同时访问生成多个实例

如何满足单例&#xff1a;1.构造方法是private、static方法、if语句判断 ①、单线程 Single类 //Single类&#xff0c;定义一个GetInstance操作&#xff0c;允许客户访问它的唯一实例。GetInstance是一个静态方法&#xff0c;主要负责创建自己的唯一实例 public class LazySi…

八大排序算法--快速排序(动图理解)

快速排序 概念 快速排序是对冒泡排序的一种改进。其基本原理是通过选取一个基准元素&#xff0c;将数组划分为两个子数组&#xff0c;分别对子数组进行排序&#xff0c;最终实现整个数组的有序排列。快速排序的时间复杂度最好为O(nlogn)&#xff0c;最坏为O(n^2)&#xff0c;…

Jupyter Notebook 7重磅发布,新增多个特性!

本文分享Jupyter Notebook大版本v7.0.0更新亮点&#xff0c;及简单测试&#xff01; 近日&#xff0c;Jupyter Notebook大版本v7.0.0更新&#xff0c;Jupyter Notebook 7基于JupyterLab&#xff0c;因此它包含了过去几年JupyterLab中添加的许多新功能和改进&#xff0c;部分亮…

学习笔记——压力测试案例,监控平台

测试案例 # 最简单的部署方式直接单机启动 nohup java -jar lesson-one-0.0.1-SNAPSHOT.jar > ./server.log 2>&1 &然后配置执行计划&#xff1a; 新建一个执行计划 配置请求路径 配置断言配置响应持续时间断言 然后配置一些查看结果的统计报表或者图形 然后我…