秒懂C++之进程状态及优先级

fe594ea5bf754ddbb223a54d8fb1e7bc.gif

目录

 

一.进程状态

1.1 进程排队

1.2 进程状态

运行状态

阻塞状态

挂起状态

二.Linux环境下的进程状态

R运行状态

S睡眠状态

D磁盘休眠状态

T停止状态

X死亡状态

Z僵尸进程状态

三.进程优先级

基本概念

查看系统进程

用top命令更改已存在进程的nice


一.进程状态

1.1 进程排队

在聊进程状态之前先来聊聊进程排队——队列~

当我们的进程需要排队时,就说明它正在等待某种资源~

就比如上述代码~我们就需要等待键盘输入数据,而这正是硬件资源的等待~

进程排队,那一定是进程的PCB(task_struct)在排队,因为是操作系统在管理排队~

借助排队我们来重新认识PCB,在之前的学习中为了让多个进程组织在一起,我们是直接在结构体内定义一个指向下一位结构体的指针Next~

而实际上为了能让组织后可以适配多种数据结构,我们是像上图这么构建的~在PCB内部放一个结构体struct listnode,里面存放指向下一个与上一个结构体的指针~

实际上PCB中存在很多这种类似struct listnode的结构体,我们通过选择它们的链接方式来组织成对应的数据结构~

就比如在进程排队时,我们就可以让可执行程序指向进程的链表接口(蓝色箭头),这样操作系统就可以利用该数据结构的特性进行数据上的管理~

这是多样性的,往后可执行程序也可以接入链式栈,单链表等等数据结构接口~而我们在进程排队中往往是用数据结构中的队列进行组织管理(因为队列底层就是双向链表),所以这里用双向的结构~

那么问题来了~如果可执行程序指向了结构体处,那么我们前面部分的属性又怎么访问呢?

1.2 进程状态

通常我们对于进程状态的表述一般概况为运行,阻塞以及挂起~

所谓的状态其实就是对应的整型变量,放置在PCB中~

而状态决定了该进程的后续动作~

运行状态

只要处在运行队列中,那就是运行状态~

阻塞状态

如果出现了需要访问硬件资源的时候那么操作系统就会把该PCB移出运行队列链接到底层队列中去~直到我们的硬件资源响应并让操作系统核查后才会移出阻塞队列,重新回到运行队列排队~

挂起状态

因为在阻塞的时候还在等待资源却又占着位置,所以操作系统会把代码与数据唤出拷贝到磁盘的swap分区中,只有等到CPU重新准备调度时才会唤入回来~

在这个过程中PCB是还在内存中的,它要保证呈现该进程的状态~而且创建进程的时候也是先生成PCB,相当于学生档案和学生,学校会在学生入学前通过学生档案获取信息提前管理~

二.Linux环境下的进程状态

R运行状态

R运行状态(running): 并不意味着进程一定在运行中,它表明进程要么是在运行中要么在运行队列里。

我们之所以注释掉printf与sleep是因为我们的代码太短了,cpu处理也就一瞬间的事情,并且printf涉及到硬件设备(显示屏打印)的访问,与外设交流的效率太慢了,也会来不及刷新而一直处于S+休眠状态。 所以我们把这两个因素排除后就是R运行状态了~
  • 有+,代表前台进程,可以用ctrl + c 强制暂停
  • 无+,代表后台进程,不可以用ctrl + c 强制暂停,只能用kill -9杀死进程

S睡眠状态

S睡眠状态(sleeping): 意味着进程在等待事件完成(这里的睡眠有时候也叫做可中断睡眠
(interruptible sleep))。
当我们需要从键盘输入即进程需要访问硬件资源的时候,该进程会进入到阻塞队列中~
所以S睡眠状态就相当于阻塞状态~

D磁盘休眠状态

D磁盘休眠状态(Disk sleep)有时候也叫不可中断睡眠状态(uninterruptible sleep),在这个状态的进程通常会等待IO的结束。
该状态也被称之为免死金牌~
操作系统会在内存极度拥挤的情况下会选择直接杀掉进程~而D状态就是被标记保护的进程,这时候的操作系统就不会杀掉该进程~
该进程状态也是相当于阻塞状态

T停止状态

T停止状态(stopped): 可以通过发送 SIGSTOP 信号给进程来停止(T)进程。这个被暂停的进程可以通过发送 SIGCONT 信号让进程继续运行。

 

我们使用指令kill -19对进程发送停止信号,这时候就会变成停止状态,然后再使用指令kill -18发送启动信号,这时候就会恢复启动,不过状态会变成S转为后台进程~只能用kill -9杀死 

X死亡状态

X死亡状态(dead):这个状态只是一个返回状态,你不会在任务列表里看到这个状态。

Z僵尸进程状态

僵死状态(Zombies)是一个比较特殊的状态。当进程退出并且父进程(使用wait()系统调用,后面讲) 没有读取到子进程退出的返回代码时就会产生僵死(尸)进程

这里我们用类比来解释僵尸进程~

假如一个人突然死亡,那么到来的警察并不会立刻处理尸体,而是会封锁现场等待法医来鉴定他的死因~

而我们的进程退出的时候就相当于尸体,代码和数据可以直接释放,因为不会执行~但是它的PCB要缓一下等待其他进程来读取退出的数据(等待法医来鉴定)

那fork函数形成的父进程与子进程举例~

如果子进程在退出的时候父进程不去读取它的数据,那么PCB对象也会一直在内存中,而这都是会占据内存的,最终会导致内存泄漏~

我们一开始只让子进程循环5次后就退出进程,然后父进程一直循环下去但不去获取子进程的退出数据~ 那么这时候的子进程就会变成僵尸进程状态~

如果是父进程先退出呢?(bash会自动读取其进程状态),那么子进程怎么办呢?它总有结束推出的时候,谁去回收它的推出数据呢?

父进程先退出的情况下会由1号进程(操作系统)所领养,最终会由1号进程去获取它的退出数据~

不过被领养后会从前台进程变为后台进程~

而这种情况下的子进程又被称之为孤儿进程~

三.进程优先级

基本概念

  • cpu资源分配的先后顺序,就是指进程的优先权(priority)。
  • 优先权高的进程有优先执行权利。配置进程优先权对多任务环境的linux很有用,可以改善系统性能。
  • 还可以把进程运行到指定的CPU上,这样一来,把不重要的进程安排到某个CPU,可以大大改善系统整体性能

优先级中数字越小,优先级越高~ 

查看系统进程

linux或者unix系统中,用ps –l命令则会类似输出以下几个内容: 

LINUX下PRI默认优先级都为80~

而我们通常是通过修改nice的数值来改变优先级 

top命令更改已存在进程的nice

  • top
  • 进入top后按“r”–>输入进程PID–>输入nice值

 

优先级是有界限的~

这样nice其实也有界限【-20,19】一旦超出一律按界值处理~

 

  • 27
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值