linux_进程状态

news2024/11/14 1:50:29

目录

一. 概念铺设

状态是什么?

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

二. 传统操作系统状态

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.coloradmin.cn/o/811244.html

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

相关文章

hadoop部署配置

端口名称 Hadoop2.x Hadoop3.x NameNode内部通信端口 8020 / 9000 8020 / 9000/9820 NameNode HTTP UI 50070 9870 MapReduce查看执行任务端口 8088 8088 历史服务器通信端口 19888 19888 端口名称Hadoop2.xHadoop3.xNameNode内部通信端口8020 / 90008020 / 9000/9820NameNode…

延长周末,获得高质量休息:工作与学习党的生活策略

&#x1f337;&#x1f341; 博主猫头虎 带您 Go to New World.✨&#x1f341; &#x1f984; 博客首页——猫头虎的博客&#x1f390; &#x1f433;《面试题大全专栏》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33a; &a…

【Linux】多线程的补充

1 线程安全的单例模式 1.1 什么是单例模式 单例模式是一种 "经典的, 常用的, 常考的" 设计模式. 1.2 什么是设计模式 IT行业这么火, 涌入的人很多. 俗话说林子大了啥鸟都有. 大佬和菜鸡们两极分化的越来越严重. 为了让菜鸡们不太拖大佬的后腿, 于是大佬们针对一些…

从源码角度配合网络编程函数API 分析下 三握手四挥手都做了什么

首先我们先说下网络编程API&#xff1a; 数据在网络上通信&#xff0c;通信的双方一个是 客户端&#xff0c; 一个是 服务器 更具体来说&#xff0c;不是 客户端和服务器这两个机器在 经由互联网 进行通信&#xff0c; 而是 客户端上的某一进程 与 服务器端的某一进程 进…

Vue2 第七节 Vue监测数据更新原理

&#xff08;1&#xff09;Vue会监视data中所有层次的数据 &#xff08;2&#xff09;如何监测对象中的数据 通过setter实现监视&#xff0c;且要在new Vue时传入要监测的数据对象中后追加的属性&#xff0c;Vue默认不做响应式处理如果要给后添加的属性做响应式&#xff0c;使…

【笔记】PyTorch DDP 与 Ring-AllReduce

转载请注明出处&#xff1a;小锋学长生活大爆炸[xfxuezhang.cn] 文内若有错误&#xff0c;欢迎指出&#xff01; 今天我想跟大家分享的是一篇虽然有点老&#xff0c;但是很经典的文章&#xff0c;这是一个在分布式训练中会用到的一项技术&#xff0c; 实际上叫ringallreduce。 …

Hyper-v 设置静态IP 搭建集群

背景 最近想在本机WIN11上创建几个Centos用于做几个试验&#xff0c;之前一直用VMWare&#xff0c;需要安装额外的软件&#xff0c;正好win自带虚拟机功能&#xff0c;只需要在功能中安装Hyper-v就可以使用。 新建虚拟机 虚拟机交换器 Hyper-V 虚拟交换机是基于软件的第 2 层…

P5691 [NOI2001] 方程的解数

题目 思路 暴搜显然会TLE&#xff0c;所以这时候就应该请出DFS的伙伴——折半搜索&#xff08;meet in the middle&#xff09;了 折半搜索的思路就是先搜完后一半后&#xff0c;借助这一半的数据来搜索前一半&#xff0c;效率是原来的2倍 这个题怎么才能折半搜索呢&#xff1…

链表OJ题目1 (移除链表元素)

力扣&#xff08;链接放这里喽&#xff09; 先贴代码再做讲解&#xff1a; struct ListNode* removeElements(struct ListNode* head, int val) {struct ListNode* cur head;struct ListNode* tail NULL;while(cur){if(cur->val val){if(cur head){head head->next…

【点云处理教程】01如何创建和可视化点云

一、说明 本文是系列教程&#xff0c;专门介绍点云处理的全流程&#xff0c;是一个入门工具。“点云处理”教程对初学者友好&#xff0c;我们将在其中简单地介绍从数据准备到数据分割和分类的点云处理管道。 第1条&#xff1a;点云处理简介文章2&#xff1a;在Python中从深度图…

Python入门【可变参数、lambda表达式和匿名函数、eval()函数、递归函数、嵌套函数(内部函数)、 nonlocal关键字】(十二)

&#x1f44f;作者简介&#xff1a;大家好&#xff0c;我是爱敲代码的小王&#xff0c;CSDN博客博主,Python小白 &#x1f4d5;系列专栏&#xff1a;python入门到实战、Python爬虫开发、Python办公自动化、Python数据分析、Python前后端开发 &#x1f4e7;如果文章知识点有错误…

怎么对XMind思维导图加密?

在现代社会中&#xff0c;信息安全变得越来越重要。对于那些使用XMind思维导图来组织和管理重要信息的人来说&#xff0c;保护思维导图中的内容免受未经授权的访问变得至关重要。本文将介绍如何加密XMind思维导图&#xff0c;以确保您的信息安全。 什么是XMind思维导图&#x…

Qt中postevent造成内存泄漏问题的通用解决方案

在Qt中由QCoreApplication统一管理Qt事件的收发和销毁,其中sendEvent为阻塞式发送,用于单线程的事件发送;postevent为非阻塞式发送,构造事件的线程和接受事件的线程可以为两个线程。 最近在做一个个人项目ShaderLab 需要绘制OpenGL实时渲染的图像,由于OpenGL渲染基本都放…

Flowable-服务-消息任务

文章目录 定义图形标记XML内容集成Rabbitmq引入pom包配置rabbitmq 操作界面 定义 Mq 任务不是 BPMN 2.0 规范定义的官方任务&#xff0c;在 Flowable 中&#xff0c;Mq 任务是作为一种特殊的服务 任务来实现的&#xff0c;主要做Mq消息发送。 图形标记 由于 Mq 任务不是 BPM…

openGauss学习笔记-25 openGauss 聚集函数

文章目录 openGauss学习笔记-25 openGauss 聚集函数25.1 sum(expression)25.2 max(expression)25.3 min(expression)25.4 avg(expression)25.5 count(expression)25.6 count(*)25.7 delta25.8 mode() within group (order by value anyelement) openGauss学习笔记-25 openGauss…

Vue『卡片拖拽式课程表』

Vue『卡片拖拽式课程表』 概述 在本篇技术博客中&#xff0c;我们将介绍一个使用Vue实现的『卡片拖拽式课程表』。这个课程表允许用户通过拖拽课程卡片来安排不同的课程在时间表上的位置。我们将逐步讲解代码实现&#xff0c;包括课程表的布局、拖拽功能的实现&#xff0c;以…

mac使用brew切换node的版本号

借用的是这篇文章 》 mac 使用brew切换node版本 # 查看node的版本号 brew search node# 安装其他版本. 选择 node16版本 brew install node16# 如果你是第一次安装node的话&#xff0c;执行下面这个操作 brew link --overwrite --force node16# 如果你是第二次安装node的话&am…

一文教会你单向链表

目录 一、什么是链表&#xff1f; 1.链表的定义 2.链表的实现 2.1链表的定义 2.2创建一个链表 二、链表的各个接口 1.创建节点 2.头插(将新创建的节点作为头插入到链表中) 3.打印链表 4.尾插(将新创建的节点插入到链表的末端) 5.头删 6.尾删 7.查找 8.删除指定节点位…

C语言基础入门详解三

前些天发现了一个蛮有意思的人工智能学习网站,8个字形容一下"通俗易懂&#xff0c;风趣幽默"&#xff0c;感觉非常有意思,忍不住分享一下给大家。 &#x1f449;点击跳转到教程 一、C语言之函数指针 #include<stdio.h> #include<stdlib.h> /**函数指针 …

基于BIM+AI的建筑能源优化模型【神经网络】

推荐&#xff1a;用 NSDT设计器 快速搭建可编程3D场景。 AEC&#xff08;建筑、工程、施工&#xff09;行业的BIM 技术&#xff0c;允许在实际施工开始之前虚拟地建造建筑物&#xff1b; 这带来了许多有形和无形的好处&#xff1a;减少成本超支、更有效的协调、增强决策权等等。…