进程状态分析

目录

什么是进程:

查看进程的方式:

显示所有进程

打印第一行的信息

显示指定进程

保存进程的目录proc

PID

获取pid的方式1

获取进程的方式2--系统调用

PPID

验证proc的实时性

认识当前路径

fork() 创建子进程

性质

为何父进程返回的是子进程的pid,子进程返回0?

操作系统的进程状态

运行态

终止态

阻塞态

挂起态

Linux下的进程状态

R--运行状态

阻塞状态 

S--浅睡眠状态

D--深度睡眠

Z和X--僵尸状态和死亡状态

孤儿进程

T--暂停状态

t--追踪状态


什么是进程:

在 Linux 下跑起来的程序就叫做进程;

可以和文件对比来理解,我们知道 文件是由文件内容和文件属性组成的,而进程是由自己的属性和对应的文件组成,在操作系统中,进程的数据和属性存在PCB中,在Linux中,PCB等于task_struct;

操作系统通过对 task_struct 来管理进程,就相当于在大学,学校通过对我们的数据属性来管理我们一样;

进程 = task_struct + 文件(文件属性+文件内容)

查看进程的方式:

当一段代码编译好后生成可执行程序后,当执行这个可执行程序,必然会产生一个以可执行程序同名的进程,那么进程如何查看呢?

显示所有进程

ps ajx

打印第一行的信息

ps ajx | head -1

显示指定进程

ps ajx | grep 进程名

ps ajx | grep 进程名 | grep -v grep

grep -v grep可以去掉grep的进程:

ps ajx | head -1 && ps ajx | grep 进程名 | grep -v grep

打印第一行信息和指定进程:

保存进程的目录proc

目录 proc 保存的是当前系统的实时进程信息,我们可以通过 进程对应的 PID来验证此目录

PID

进程的一个进程只有一个pid,pid与进程相互对应,在 proc 目录下,存有进程的pid:

获取pid的方式1

上述用 ps ajx 来查看进程的信息,可以获取到进程的 pid :

获取进程的方式2--系统调用

系统调用的方式:

对比两种方式,我们发现同一个进程,pid不同,原因是因为当一个进程结束后,再次调用此进程,系统会重新分配空间给进程,pid也会改变;

与创建变量,每一次运行时变量地址都不同是一个道理

PPID

ppid是父进程,父进程控制子进程,通过子进程来完成一个程序的执行

可以通过上述两种方式查看,这里看一下系统调用的方式:

验证proc的实时性

进程既然已经存在了,那么proc中一定存在此进程的pid:

若此时我们结束掉此进程:

再次开始进程:

认识当前路径

cwd:进程当前的工作路径;

进行文件操作时,默认文件的创建路径是当前路径,这个当前路径指的就是 cwd -> 进程的工作路径

exe:进程对应的可执行程序的磁盘文件

fork() 创建子进程

我们用 ./ 来将程序运行起来,起始就是手动创建了一个子进程,除了手动创建,还可以通过系统调用来创建子进程

性质

调用成功,给子进程返回 0,父进程返回子进程的 pid

有两个返回值

调用失败,返回 -1

子进程也会有自己的 task_struct 来存储自己的属性,其中 task_struct 内的大部分数据都是从父进程的 task_struct 中继承下来的;

fork() 以上和父进程执行相同的代码;

fork() 以下的代码段共享:父进程和子进程通过变量的返回值不同,执行不同的代码块,代码共享,子进程无自己的代码,但是数据独立,有自己的数据

因此同一个变量,能打印出来两个不同的值

为何父进程返回的是子进程的pid,子进程返回0?

为了识别子进程,一个父进程下可能会有多个子进程,将子进程的pid返回给父进程,父进程可以快速的识别这是哪一个子进程;

子进程返回0,可以知道自己被创建成功了,并且子进程找父进程的成本低,直接系统调用就可以了,因此简单的返回一个0就可以了。

操作系统的进程状态

运行态

只要 PCB 在运行队列中,那么此进程就叫做运行态,代表已经准备好了,可以随时调度

终止态

进程还在,只不过永远不在运行了,随时等待被释放;为什么不是立即被释放呢?因为操作系统可能在进行其他操作,不能理解释放,所以才有了终止态

阻塞态

进程申请 cpu 资源进行执行操作,需要在其队列中排队;那么申请其他资源:网卡、磁盘、音响等,也是需要在对应资源的队列中排队的;

当 cpu 执行到一个进程时,此进程需要调用其他资源,但是资源还没有准备好,那么此进程的 PCB 将会从 cpu 的运行队列转移到需要调用的资源的运行队列中等待,不会执行此进程,不会阻挠 cpu 调用其他进程,此时这个进程就是卡住的状态,叫做进程阻塞。

挂起态

在 cpu 运行队列中的进程,他们的代码和数据是被加载到了内存中的,当内存不够用的情况下,操作系统会将短期内不会被 cpu 调度的进程的代码和数据置换到磁盘上

Linux下的进程状态

R--运行状态

以不用调用外设的死循环为例,cpu 一直在调用此进程,那么它就为运行态:

阻塞状态 

S--浅睡眠状态

linux下的浅睡眠状态可以被随时唤起、可以被手动终止,因此又称为可中断睡眠

进程要访问非磁盘的外设时,总是需要等待资源就绪的,Linux下的PCB叫做 task_struct ,task_struct会在资源的运行队列中等待,这就是浅睡眠状态:

我们在运行,为什么是阻塞态?

因为 cpu 处理进程的速度是非常快的,外设的访问速度是跟不上cpu的处理速度的,在调用进程的时候,大部分的时间都是在等待外设资源就绪,因此这里的进程是阻塞状态;

D--深度睡眠

disk sleep--深度睡眠状态,如果进程等待的外设是磁盘资源,那么此进程就是深度睡眠状态

如何理解:

在内存不够用,进程过多,服务器压力过大时,可能会终止掉一些进程;

在一个进程要将大量数据写入磁盘中,在写入过程中,进程会将自己设置成深度睡眠状态,等待磁盘的写入失败或者成功的消息,防止被操作系统终止造成数据丢失。

结论:深度睡眠可以防止被操作系统终止掉;等待磁盘资源就绪,也是阻塞状态

Z和X--僵尸状态和死亡状态

死亡状态:资源可以立马回收

僵尸状态:在Linux下,当进程退出的时候,一般不会直接进入死亡状态,而是进入僵尸状态,僵尸状态存储着这个进程的执行结果,维护着退出信息,通过僵尸状态来告知操作系统此进程是否需要终止。

因为父进程控制着子进程,父进程不回收子进程,子进程会一直保持僵尸状态,没有用的进程还不能被释放占据着空间,这是内存泄漏!!

孤儿进程

如果父进程提前退出,子进程还在运行,那么子进程会被一号进程领养,被领养的子进程就叫做孤儿进程:

#include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
 #include <sys/types.h>
 int main()
 {
   pid_t id = fork();
   if(id==0)
   {
     int j = 1;
     while(j++)
     {
       if(j>4)
       {
         printf("我是子进程,我已经孤儿了\n");
         sleep(1);
       }
       else
       {
         printf("我是子进程,我马上孤儿了\n");
         sleep(1);
       }
     }
   }
    else
    {
      int n = 4;
      while(n--)
      {
        printf("我是父进程,我还有%d秒退出了\n",n);
        sleep(1);
      }
      exit(0);                                                                          
    }
  return 0;
 }

此时有一个问题,我们 Ctrl + C 不能结束掉孤儿进程,因为它变成了后台进程

 必须要用命令将其终止掉:

T--暂停状态

当一个进程运行时,用命令传递信号令其暂停

kill -19 pid

此时这个孤儿进程就是暂停状态

//继续进程
kill -18 pid

t--追踪状态

暂停状态的一种,在gdb调试中,打上断点,运行至断点处即可:

  • 9
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 10
    评论
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

今年依旧去年春

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值