当前位置: 首页 > ds >正文

进程状态 + 进程优先级切换调度-进程概念(5)

文章目录

  • Linux 具体的进程状态
    • 1. D(disk sleep)状态
    • 2. X(dead)与 Z(zombile)状态
    • 3. 如何模拟验证Z状态
    • 4. slab 技术的补充
  • 进程优先级切换调度(13-0.00.00)
    • 1. 孤儿进程
    • 2. 进程的优先级(13-0.25.00)
    • 3. 优先级的具体操作

Linux 具体的进程状态

1. D(disk sleep)状态

D状态被称作不可中断休眠或深度睡眠,可能跟磁盘有关系, 这里举个例子进行说明

现在有一个进程要写入100MB数据到磁盘,写入的过程中是有可能中断的,但无论如何,磁盘都会将写入结果返回给进程,进程再告诉用户。而磁盘在拷贝这100MB这份资源期间,进程啥也干不了,它要等磁盘的拷贝结果,此时进程就处于S状态。

但是当系统资源严重不足的时候,操作系统在极端的情况下会采取杀进程的方式释放空间(比如你手机软件有时会直接闪退),那如果这个进程被杀掉了,磁盘手里拿着这100MB的数据不知道该怎么办,跟进程讲也没有啥反应,就只好将其扔掉了,那在系统层面上就丢失了这100MB数据,而且用户还不知道

最为关键的是,操作系统,磁盘,进程,站在各自的角度看哪个都没有错。比如操作系统,它要不杀进程释放资源,那操作系统崩了,全部都得炸。进程它是直接被杀掉的,还是个受害者,没一点办法。磁盘委屈地说,我有啥问题,我都跟进程讲了,让它等我等我

所以此后就出现了D状态,当进程处于D状态时。操作系统就无权杀掉该进程,该进程也有权不对任何杀掉的动作进行响应

因此阻塞状态包括了两种:S与D,那这D状态就只能等它自己醒过来,或者直接重启,还有可能需要断电,才会将该进程直接杀掉

另外再补充一点其它的,输入命令:kill -l,可以查看能发送的信号,目前为止其中用的多是9(kill -9 进程UID),18,19。这三者分别是杀进程,进程继续,进程暂停

在这里插入图片描述

2. X(dead)与 Z(zombile)状态

X被称作死亡状态,也就是结束状态。Z被称作僵尸状态(zombile:僵尸),这里还是举个例子来帮助理解

你今天突然遇到一个人倒在了马路边,走上去用手感知,发现这个人没呼吸了,已经死了。这时你赶紧打110,说哪里哪里死了个人,警察来到现场后,会直接将尸体抬走并通知家属吗?

肯定是不会的啊,先封锁现场,让法医进行分析和解剖,直至法医获取到足够的信息,那在这段时间内这个进程所处的状态就是Z状态,就是为了获取进程的退出信息,当法官跟警察说通知家属,把人带走处理后事,这个人才真正死亡,也就是处于X状态

那为啥要存在僵尸状态呢?首先,我们创建子进程的目的是为了让进程完成某种事情的,那最后结果相关的信息(相关信息存储在task_struct中)父进程得知道吧

因此一个子进程要退出了,它并不是一退出就立马将PCB,代码和数据全部释放掉,当一个进程退出时,操作系统可以将这个进程的代码和数据全部释放掉,因为这个进程并不会被调度了

但是它的PCB信息是不能被释放的,必须将自己退出的信息暂时维持处,因为父进程需要从子进程的PCB里获取到子进程退出的结果

在子进程退出之后,父进程获取子进程退出信息之前,此时进程所处的状态就称之为Z状态

3. 如何模拟验证Z状态

创建父,子进程,让子进程在一定程度下直接退出,然后就能查到子进程退出后所处的状态

下面代码中,手动创建一个子进程,让子进程代码循环五次,自动结束。而父进程代码一直处于循环中,此时子进程已经退出了,而父进程仍在运行当中

int main()
{pid_t id = fork();if(id == 0){//childint count = 5;while(count){printf("我是子进程,我正在运行: %d\n", count);sleep(1);count--;}}else {while(1){printf("我是父进程,我正在运行...\n");sleep(1);}}return 0;
}

在这里插入图片描述

从图片中也能看出,如果父进程一直不管,不获取子进程的退出信息,那么子进程就会一直处于僵尸状态,这样就会造成内存泄漏的问题,这个内存泄漏问题和下面内存泄漏问题造成的原因不同

在咱们写代码时,malloc或new出一片空间,但是忘记及时释放了,此时也会出现内存泄漏问题,那该进程退出了,内存泄漏问题还存不存在呢?不存在

进程一旦退出了,该内存泄漏的问题自然而然地就被解决了,也就是被自动回收了,而上面僵尸状态下的内存泄露的问题是系统层面上的,操作系统做不到回收该PCB

什么样的进程具有内存泄漏问题是比较麻烦的呢,常驻内存的进程。常驻内存的进程:经常驻扎在内存中的进程,一旦启动该进程,基本上不会退出,一直死循环的那种(比如steam上的那个wallpaper软件)

4. slab 技术的补充

在这里插入图片描述

可以构建了一个unuse链表,原先的那个进程从Z状态变成X状态后,那个PCB不是要被释放吗?但是,我可以将要释放的PCB放到这个unuse链表中

等到后面操作系统要再创建(malloc)一个task_struct时,就能直接在这个链表中选择一个task_struct,将结构体里面的成员初始化,那这个task_struct结构体不就能够复用了吗

这样就形成了一个类似于内核当中的数据结构对象的缓存,所以在操作系统内它就可以加速我们创建进程和释放进程的速度,这种技术在Linux内核里叫做slab

进程优先级切换调度(13-0.00.00)

1. 孤儿进程

  • 父进程如果提前退出,那么子进程后退出,子进程进入Z之后,那该如何处理呢?
  • 父进程先退出,子进程就称之为孤儿进程
  • 孤儿进程被1号init/systemd进程领养,当然也要由init/systemd进程回收
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>int main()
{pid_t id = fork();if(id == 0){// childwhile(1){printf("我是一个子进程, pid: %d, ppid: %d\n", getpid(), getppid());sleep(1);}}else{// fatherint cnt = 5;while(cnt){printf("我是一个父进程, pid: %d, ppid: %d\n", getpid(), getppid());cnt--;sleep(1);}}return 0;
}

在这里插入图片描述

父子进程关系中,如果父进程先退出,子进程就要被1号(操作系统)进程领养,这个被领养的子进程就叫做孤儿进程

那为什么要领养子进程呢?如果不领养的话,子进程进入僵尸状态之后,就没有父进程帮忙回收,此时就会造成内存泄漏问题

当进程变成孤儿进程,此时的进程就处于后台进程(./cmd &),从图片中也能看到子进程的状态从S+S

当该孤儿进程运行起来之后,命令ctrl + c就无法杀掉,也就是无法杀掉后台进程,同时后台进程能向前台打印消息

只能kill -9 孤儿进程的PID,这样才能将孤儿进程给杀掉

2. 进程的优先级(13-0.25.00)

  • 进程的优先级是什么:进程得到CPU资源的先后顺序。这里将优先级和权限区分开来,权限是否能得到某种资源,优先级是一定能得到资源,只不过是先后的问题
  • 为什么会存在进程的优先级:那进程为啥会在CPU上排队呢?因为目标资源稀缺,导致操作系统要通过优先级来确认谁先谁后使用资源的问题

3. 优先级的具体操作

优先级其实也是一种数字(int类型),task_struct的一种属性,值越低,优先级越高,反之优先级越低

基于时间片的分时操作系统,会考虑到公平性,也就是各进程优先级值要相差不大,优先级可能变化,但是变化幅度不能太大

在这里插入图片描述

UIDuser id,就是用户ID。人名是给用户看的,操作系统中是看UID,进程启动时会将UID给保存下来,记录这个进程是哪个用户启动的

用户跟操作系统打交道,都是通过进程来进行,用户所有的请求和任何都会转换成进程,被操作系统去调度和执行。所以识别权限并不是去识别用户的,是识别进程和文件之间的权限

带上选项n,显示出用户ID
在这里插入图片描述

那系统怎么知道我访问文件的时候,是拥有者,所属组,还是other呢?在Linux系统中,访问任何资源,都是进程去访问,进程就代表用户,OS它会拿着进程的UID依次去匹配文件的拥有者,所属组,other

http://www.xdnf.cn/news/15306.html

相关文章:

  • 【C++篇】二叉树进阶(上篇):二叉搜索树
  • Qt中QGraphicsView类应用解析:构建高效2D图形界面的核心技术
  • 数据结构-顺序表
  • 【C语言网络编程】HTTP 客户端请求(域名解析过程)
  • Oracle字符类型详解:VARCHAR、VARCHAR2与CHAR的区别
  • Qt数据库编程详解:SQLite实战指南
  • 解决Linux绑定失败地址已使用(端口被占用)的问题
  • 设计仿真 | MSC Apex Simufact实现铁路铰链轻量化与高精度增材制造
  • 在 Spring Boot 中优化长轮询(Long Polling)连接频繁建立销毁问题
  • MySQL:分析表锁的常见问题
  • JavaScript加强篇——第四章 日期对象与DOM节点(基础)
  • P9755 [CSP-S 2023] 种树
  • 【JavaScript高级】构造函数、原型链与数据处理
  • OS16.【Linux】冯依诺曼体系结构和操作系统的浅层理解
  • docker-compose安装常用中间件
  • 【unitrix】 4.21 类型级二进制数基本结构体(types.rs)
  • 1965–2022年中国大陆高分辨率分部门用水数据集,包含:灌溉用水、工业制造用水、生活用水和火电冷却
  • C语言的程序控制语句
  • VR协作海外云:跨国企业沉浸式办公解决方案
  • 决策树算法在医学影像诊断中的广泛应用
  • ch07 题解
  • 番外-linux系统运行.net framework 4.0的项目
  • [特殊字符]远程服务器配置pytorch环境
  • 设计模式笔记_结构型_代理模式
  • 基于vscode开发工具显示git提交信息的插件
  • 世界现存燃油汽车品牌起源国别梳理
  • 【实时Linux实战系列】硬实时与软实时设计模式
  • 【网络】Linux 内核优化实战 - net.netfilter.nf_conntrack_max
  • 基于开源AI智能名片链动2+1模式与S2B2C商城小程序的渠道选择策略研究
  • BPE(Byte Pair Encoding)分词算法