[Linux从无到有] 进程
Posted 一个正直的男孩
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[Linux从无到有] 进程相关的知识,希望对你有一定的参考价值。
1. 进程
大家应该对任务管理并不陌生吧,有时候app卡死了我们就需要手动去吧这个app杀死,但仔细看会发现他上面写的是进程
简单来说,一般点开app就是把软件的代码和数据加载到内存中,这样算是一个进程了,但是其实内部还进行了更多的操作,他还会为这个代码创建一个PCB(sask_struct)
1.2 PCB
什么是PCB?
进程控制块,用来描述进程属性的集合
为什么需要PCB?
一般情况下进程是不止一个的,所以CPU需要对进程管理,切上述说过一个概念管理者与于被管理者,而CPU就是管理者,进程就是背管理者,一般管理者是不直接管理被管理者,一般通过数据管理的
PCB中包含的信息(部分)
- 上下文数据
- 内存指针
- 状态
- 优先级
- 标识符
- 程序计数器
- IO状态
- 记账信息
1.2.1上下文数据
CPU一直奉行一个概念:公平至上,效率为优,就是CPU不会偏心他每一个进程都会雨露均沾,所以这里就有一个概念叫做时间片
时间片:
微观是就是分配给每个进程在CPU上的运行时间
当一个进程的时间片到了,或者来了一个优先级更高的进程,那么CPU就要把他剥离下来,而剥离下来的时候会将CPU寄存器中的信息(运行信息),程序计数器(pc指针,存的是下个代码的地址),程序状态,保存至PCB中,整个就是上下文数据的简单概念
并发
老话说眼见为实,耳听为虚,其实现在我告诉你,眼见也不一定为实,我们平时在电脑上打开多个app,在上述操作中可以理解CPU是同时在运行多个进程,这就是眼睛欺骗了你,他只让你看到了他的表面,底层其实是cpu在疯狂的切换(每个进程都有对应的时间片),让你觉得其实CPU在执行多个进程
并行
本质就是有钱,一台机子俩CPU,那么CPU就可以在同一时间运行俩个进程,只要钱够多,同时跑百八十个进程都没事
途中可以清晰的看出在一段时间内并发与并行的运行原理,且他们剥离后会放到运行队列中等待
并发:一段时间内运行多个进程
并行:同一时间可以运行多个进程(取决于cpu个数)
运行队列等待:
1.2.3状态
上面的是宏观的进程状态图,且每个操作系统可能对应的状态有所不同,我们讲的linux下的状态
- R 运行状态
- S 睡眠状态
- D 深度睡眠(磁盘休眠)
- T 停止状态
- Z 僵尸状态
- X 死亡状态
R状态
R既然是运行状态,那么他是CPU在运行的吗?
当然不是,上面说过,每个进程都有一个时间片,运行完就剥离下来,还需要运行就放到运行队列中,那么其实在运行队列中的进程也是R状态
D状态 VS S状态
S和D都是睡眠状态
S,D都意味着进程在等待事件完成,但是S是可以被中断唤醒了(外部给一个指令),D是只能等着进程自动醒来
不知道你有没有遇到过这样的场景就是你想关机却卡死了,其实就是有进程在深度睡眠(D),阻止你关机,现在是不是多年的谜团就解破了,D状态一般是进程在进行重要的操作,如往磁盘中塞数据……
T状态
该状态可以理解为在调试,启动调试不就停在了短点出吗,他也是类似,进程直接停止,需要发送SIGSTOP才可以继续,这就和我们按下n,s(Linux中gdb下一步与进入函数指令)他就又开始跑。
Z状态
父进程还在,可是子进程突然啥原因退出了,那么这个时候子进程就是僵尸状态,但他是僵尸状态的时候他会把自己进程的基本信息放入他的PCB中
为啥叫僵尸状态呢?
当一个进程意外退出的时候是不会马上被释放的,就和上下文数据类似,我创建进程本质是想干什么,当然是完成任务了,如果他突然挂了,那么我需要知道他是否完成了任务,如果没有完成我需要派新进程再去执行,所以僵尸状态本质:就是进程退出时候的进程状态
不处理僵尸状态会怎么样?
C和C++你动态开辟出来的数据不释放会怎么样?内存泄漏咯,那么Z状态也一样,Linux是由C语言编写(其实操作系统基本都是由C编写的),那么上述说过一个进程是由代码数据,还有对应PBC结构体,这个PCB很大很大…………
X状态
该状态一般你在任务列表是看不到的,因为一闪而过,直接被操作系统回收。
拓展介绍一个进程(孤儿进程):
人如其名,就是当子进程还在运行的时候,这时候我父进程突然也应为某种原因线子进程退出,这就是孤儿进程的概念?
你说过子进程的数据是父进程回收的那现在怎么?那么你想一想现在谁可以帮助子进程不变僵尸呢?当然是操作系统,没错当一个进程变成孤儿进程的时候,他们会去认操作系统做父亲(操作系统本质也是一个进程(1号进程))
如果我看这个进程不爽老是优先占用CPU资源那么什么办法呢?
- kill + pid
那么现在有个问题就是僵尸进程可以被杀死吗?
现在已经是逻辑题了,你说你向他心脏开了一枪后且确认已经死了,临走的时候又补了几枪算是在杀了次吗?他又不是死侍(漫威超级英雄),你那只能算鞭尸
除了僵尸且D状态也是不可以被杀死的,你关机都可以给阻拦住让你死机,你觉得一条指令可以杀死他们不要开玩笑了好吗
如何查看呢?
- 需要一条指令: ps axj |grep [进程]
- top
- ps l
建议使用第一个,因为第一个搭配grep直接筛选出你想要看的进程
那么怎么样才会看到这些状态呢?
R状态:
当你载用ps指令的时候怒有没有发现其实ps他的状态就是R
本质我们输入这个指令也创建了一个进程
t状态
当我按下回车得的时候,那么查看进程状态的时候,main.g这个进程的就变成了t
Z状态:
代码:
进程的状态:
S状态
这反而是最好看到的,只需要在代码中加一个sleep函数,或者不加进程都处于S状态(因为本质上这个进程又大一那一下在运行,大部分时间都是在睡眠所以)
孤儿进程:
当被1号进程领养后,你不发ctrl+C终止进程,你可以理解为翅膀硬了,普通的招对他没用了,这个时候需要用kill 指令进行杀除
pid和ppid与fork(创建进程)与标识符
在上面你看到右pid与ppid,这俩个是什么东西呢?
在现实生活中,你是如何被人标识的呢?
名字,外号???
这只是一部分,那么当要过年买车票回家时候你你不会和售票员说我叫xxx,给我张票我要回家,这个除非你是总统一般情况售票员小姐姐会认为你🧠有点毛病,你当然是递上你的生份证,因为上面的生份证号就代表了你,你的一切信息都可以通过他得知,而不是xxx的名字
那么pid就是你的生份证号,也就是当前进程的生份证号(标识符)
ppid为则为你的父进程的生份证号(多出的p理解为parent)
且你看到我运行的时候为啥开if 与else同时运行,这就要归功于fork()
linux中的分叉函数(其实就是创建子进程函数)
- 创建成功后,子进程返回0,父进程返回子进程的 pid,如果失败返回 -1(返回类型是pid_t 其实就是 unsigend long long的typedef)
- 创建出来的子进程的数据与代码与父进程一致(子进程创建的时和父进程共同指向一份代码,但是数据是各自私有一份的 )
- 且在运行父子进程的时候谁优先取决于操作系统
图解forke创建后,进程运行状态:
为啥需要返回子进程的pid给父进程?
你想当子进程退出后他的资源由谁回收呢?那你想你在学习里面犯事了那是谁给你擦屁股的,当然是你老爹啊。那么道理都一样当子进程退出后当然是由他的夫进程取释放喽
这个时候可能有人会问,那么父进程由谁释放?
快动用你的小脑袋瓜子想想,你父亲是那里来的,不要和我说你父亲是孙悟空,或者耶稣,当然是你爷爷奶奶生下来的呀,那么‘’爷爷‘’ 进程是啥呢?
bash其实就是命令行解释器
现在介绍完linux中的状态后我们来对应一下开始的进程状态图:
1.2.4优先级
在医院缴费的时候是否留心看到过一个一张纸条,上面写着 “军人依法优先”,虽然我没有现实中去医院没有碰到过兵哥哥,那为啥要优先,本质就是他啥都优先,抗洪救灾,保家卫国……,且缴费的窗口太少了,本质就是僧多粥少
而在计算机中也是如此,一般情况下,计算机中只搭载了一颗CPU,那么进程那么多,不也是一个僧多粥少的局面吗
优先级 vs 权限
你觉得他们的一样吗?
其实是不一样的,优先级是优先获得资源,说白了,不管怎么样最终你都会获得资源(好像看过一部电影还是电视,男主独苗叛逆,家里有钱,他爸不给他钱,最终他老爹死了,因为是独苗所以他还是获得了遗产),权限是有没有资格获得,如上面的故事,我是你家的庸人,老板死了他为啥不把钱给我,本质就是我没有这个权限
如何修改优先级
在Linux中优先级由PRI 与 NI 值控制,PRI为初始值而NI是可以影响他的优先级
NI的范围[-20,19],越小优先级就越高,优先获得资源
如图所示
需要用到的指令是top->r-> 输入pid与nice值,且每次修改都是在PRI的初始值上修改入上图所示(80)
为什么要限制NI的范围?
上述说过一个概念就是,OS的调度器的第一原则就是“公平之上,效率择优”,如果你将一个进程的优先级设为-10000000……那么这时候CPU大部分时间都在运行这个进程,那么就导致其他进程调度不到,导致饥饿问题,就如古代一些皇帝一样,自己胡吃海喝,底下民不聊生,这难道不出问题?
1.2.6 程序计数器
这个在上述提到过,学名是PC,不是电脑端的意思,他的作用指向程序下一条需要执行的代码存到寄存器中,这个过程就叫做取指令,并且在如何时刻,PC指针都指向主存的某条机器指令。
以上是关于[Linux从无到有] 进程的主要内容,如果未能解决你的问题,请参考以下文章