Linux基础4-进程2(Linux中的进程状态,R,S,D,T,t,Z,X,僵尸进程,孤儿进程)

上篇文章:Linux基础4-进程1(操作系统,进程介绍,Linux进程相关命令,getpid,fork)-CSDN博客

本章重点:

进程状态相关知识

目录

[1. 进程常见的状态](#1. 进程常见的状态)

2.普遍的操作系统理解进程状态

[3. Linux操作系统是如何区分这些状态的](#3. Linux操作系统是如何区分这些状态的)

3.Linux中查看进程状态

[3.1 R(运行状态)与 S(睡眠状态)](#3.1 R(运行状态)与 S(睡眠状态))

[3.2 T(停止状态)状态, t(短暂暂停)状态,D(深度睡眠)状态](#3.2 T(停止状态)状态, t(短暂暂停)状态,D(深度睡眠)状态)

[3.2.1 前后台进程](#3.2.1 前后台进程)

[3.2.2 t状态](#3.2.2 t状态)

[3.2.3 D状态](#3.2.3 D状态)

[4. Z状态与僵尸进程](#4. Z状态与僵尸进程)

[5. 孤儿进程](#5. 孤儿进程)

[6. 下章重点](#6. 下章重点)

[6.1 进程优先级](#6.1 进程优先级)

[6.2 进程的竞争性,独立性,并发,并行](#6.2 进程的竞争性,独立性,并发,并行)


1. 进程常见的状态

运行,新建,就绪,挂起,阻塞,等待,停止,挂机,死亡等

2.普遍的操作系统理解进程状态

在os中,os会管理一个运行队列

1 一个cpu会拥有一个运行队列

2 让进程进入运行状态的本质,将进程对象的task_struct(进程控制块PCB)放入运行队列

3 进程对象的PCB在进程队列中,该进程的状态才是运行状态,并不是进程在运行就是运行状态

4 进程会等待占用CPU资源,进程也会去占用外设的资源

5 操作系统通过将进程对象的PCB放到不同的执行队列来改变其状态

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

关于阻塞和挂起:

阻塞状态是当进程需要资源而处于等待时的状态。

阻塞状态的进程可能不会立即被调度,它会占用内存来等待资源。

但是,被阻塞的进程状态过多,内存资源会不够,这个时候操作系统就会把这些进程的数据和代码保存在磁盘上。

这样就能够节省一定的内存资源,将进程的这种状态称为挂起状态。

当被挂起的状态等待的资源到达时,操作系统再将磁盘的数据和代码加载到内存中继续运行。

两种状态之间的转化如下:

3. Linux操作系统是如何区分这些状态的

上图是Linux 代码中对进程状态的描述

有R(运行状态) S(睡眠状态) D(深度睡眠) T(停止状态) t(短暂停止) Z(僵尸状态) X(死亡状态) 七种状态

3.Linux中查看进程状态

3.1 R(运行状态)与 S(睡眠状态)

#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>

int main()
{
  while(1)
  {
    int a = 1;
    a+=1;
  }
  return 0;
}

该代码是一个死循环,方便我们观察状态

适当修改代码,死循环的同时打印a值

cpp 复制代码
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>

int main()
{
  int a = 1;
  while(1)
  {
    printf("%d\n",a);
    a+=1;
    sleep(1);
  }
  return 0;
}

这个由R状态变为S状态的原因:

printf输出到外设(显示器),进程需要等待显示器就绪,需要等待较长的时间(相对于cpu)

所以:99%显示的是S状态,1%显示的是R状态

3.2 T(停止状态)状态, t(短暂暂停)状态,D(深度睡眠)状态

cpp 复制代码
kill -19 进程pid    //可以停止这个进程
kill -18 进程pid    //可以重启暂停的进程

暂停状态是阻塞状态还是挂起状态?

对于用户来说:暂停状态就是阻塞了,是否挂起我们不知道

对于OS来说:是否要挂起阻塞状态由OS自行决定(用户不需要知道阻塞状态是否需要被挂起)

继续运行暂停的进程

使用 kill -18 之后,被暂停的process重新变成了S状态。

但是却不是变回S+,这是为什么??

我们使用 ctrl c 都无法强制退出process,这是因为process变为了后台进程

3.2.1 前后台进程

状态前面带+号的是前台进程,不带+号的是后台进程

后台进程无法使用ctrl c 终止,只能使用 kill 杀死

当一个前台进程被kill -19 暂停后,使用 kill -18恢复运行就会由前台进程变为后台进程

3.2.2 t状态

t状态是暂短暂停状态,如使用gdb调试一个进程的时候,该进程会处于t

3.2.3 D状态

在D状态下的进程无法被杀死,只有通过断电,或者进程自己醒来,自己解决

4. Z状态与僵尸进程

处于Z状态的进程称为僵尸进程。

当子进程退出之后,父进程没有读取到子进程的返回状态,子进程就会变为僵尸进程。且僵尸进程会一直等待父进程读取退出状态

子进程被创建出来 --> 为了完成任务 --> 父进程需要知道子进程完成的怎么样(通过子进程的退出信息)

当子进程退出了,父亲却没有回收子进程,这是一个问题!

只要我们创建一个父子进程,让父进程不退出,也不回收子进程。再让子进程退出,就能观察到处于僵尸状态的子进程

下面代码父亲处于死循环且不会回收子进程,子进程5秒后退出。

子进程退出之后就会变为僵尸进程

cpp 复制代码
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
int main()
{
  pid_t id=fork();
  if(id==0)//正常为子进程
  {
    //childi
    printf("我是子进程,我的pid为%d,我的ppid为%d\n",getpid(),getppid());
     sleep(5);
     exit(1);
   }
   else 
   {
     //parent
     while(1)
     {
       printf("我是父进程,我的pid为%d,我的ppid为%d\n",getpid(),getppid());
       sleep(1);
     }
   }
   return 0;
 }

僵尸进程会占用内存,又不会被回收,这样会导致内存泄漏

5. 孤儿进程

如果子进程退出,父进程不回收子进程退出信息,子进程会变为僵尸进程

如果父进程先退出,而子进程不退出会怎么样呢??

cpp 复制代码
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
int main()
{
  pid_t id=fork();
  if(id > 0)//正常为子进程
  {
    //childi
     printf("我是父进程,我的pid为%d,我的ppid为%d\n",getpid(),getppid());
     sleep(5);
     exit(1);
   }
   else 
   {
     //parent
     while(1)
     {
       printf("我是子进程,我的pid为%d,我的ppid为%d\n",getpid(),getppid());
       sleep(1);
     }
   }
   return 0;
 }

父进程比子进程先退出,子进程就会变为孤儿进程,同时被1进程收养

如果不被领养的话,子进程会变为僵尸进程,被1收养之后可以被1进程回收。这样就不会造成内存泄漏

父进程先退出

1.这种现象一定会存在 2.子进程一定会被操作系统(1进程)领养 3.如果不领养,那么子进程退出的时候,对应的僵尸进程就没人回收了

4.所以被领养的进程就是孤儿进程 5.如果是前台进程创建了子进程,如果孤儿了,那么它会自动变为后台进程

6. 下章重点

6.1 进程优先级

6.2 进程的竞争性,独立性,并发,并行

相关推荐
汪子熙23 分钟前
介绍我经常使用的两款轻便易用的 JSON 工具
linux·服务器·json
Jtti33 分钟前
怎么在FTP服务器上配置SSL/TLS?
服务器·网络·ssl
XY.散人42 分钟前
初识Linux · 进程终止
linux·运维·服务器
Lvan的前端笔记43 分钟前
linux:详解nohup命令
linux·运维·服务器
长天一色1 小时前
C语言日志类库 zlog 使用指南(第三章 “Hello World“)
linux·c语言·openeuler
好想打kuo碎1 小时前
锐捷—NAT地址映射+IPsec隧道
运维·网络·网络安全·信息与通信
bossface1 小时前
理解线程库和线程排斥(锁)
linux·运维·服务器·c语言·c++
iFulling1 小时前
【Linux实践】实验八:Shell程序的创建及变量
android·linux·服务器
BBM的开源HUB1 小时前
在 Ubuntu 24.04 VPS 部署 SoftEther VPN 服务器(一)
linux·服务器·ubuntu
水上冰石2 小时前
ubuntu 安装neo4j
linux·ubuntu·neo4j