1. 什么是进程/任务(process/tesk)?
一个程序跑起来,就开启了一个线程.我们打开电脑的任务管理器,就可以看到这里启动了哪些进程,所占的CPU资源,内存资源,磁盘最大的读取速度都可以显示出来.进程可以看作是操作系统分配资源的一个基本单位.
2. 操作系统是如何是管理进程的呢?
2.1 描述一个进程
首先介绍一下“PCB”(进程控制块)在操作系统里面主要是通过c/c++来实现相关属性,此处描述其实就是用的c语言中的“结构体”(也就和Java中的类差不多).操作系统中描述进程的这个结构体,称为“PCB”.PCB的作用是将一个进程的核心信息抽象提取出来.PCB只是一个统称,在不同操作系统中可能有其他特定的名称.
2.2 组织若干个进程
操作系统使用一些数据结构,把很多描述进程的信息给放到一起,方便进行增删查改.就是使用双向链表(实际上是多个交错的链表)来把每个进程的PCB给串起来.
简要来说:
“创建进程” -> 先创建出PCB,然后把PCB加到双向链表中.
“销毁进程” -> 找到链表上的PCB,并且从链表上删除.
“查看任务管理器” -> 遍历链表.
3. PCB中的一些属性
3.1 pid(进程id)
pid就是进程的身份标识,因此在同一时刻,同一个机器上不同的进程拥有的pid必然是不同的,不然就无法区分了.
3.2 内存指针
内存指针指明了这个进程要执行的指令在内存的哪里,以及这个进程执行指令中依赖的数据都在哪里.每当我们双击运行一个exe,此时操作系统就会把这个exe加载到内存中,开启一个进程.
3.3 文件描述符表
一个进程运行时,会操作一些文件,就是通过一个"顺序表"来记录下当前这个进程打开了哪些文件.这个属性在以后会更加详细地讲解.
4. PCB用来支撑进程调度的属性
4.1 状态
这个状态就描述了当前这个进程接下来应该怎么调度.状态基本上可以分为两种:
就绪状态:随时可以去CPU上执行.
阻塞状态:暂时不可以去CPU上执行.
在后续讲解多线程时,还会有更加细致的区分.
4.2 优先级
优先级决定了先给谁分配时间,后给谁分配时间,以及谁分的多,给谁分的少.操作系统分配资源时,也是如此,给优先级高的先分配资源,分配更多的资源.优先级低的就''没肉吃了",只能"分一口汤喝".
4.3 记账信息
记账信息统计了每个进程,都分别被执行了多久,分别都执行了哪些指令.分别都排队等了多久,目的是给进程调度提供指导依据的.
4.4 上下文
上下文记录了上次进程被调度出CPU的时候,当时程序的执行状态,下次进程上CPU的时候,就可以恢复之前的状态,然后继续往下执行.
进程在cpu执行过程中,也会产生很多的"中间结果",在进程切换出cpu前,就需要把这些中间结果(cpu的各种寄存器中的值)保存到pcb的上下文中(寄存器->内存),相当于存档.
下次这个进程回到cpu上执行时,就需要把之前的存档恢复回来(内存->寄存器),相当于读档.
5. 渣女小故事(讲讲进程调度)
假设你是一个非常完美的妹子,导致你有很多的追求者,但是原则上讲,你在同一时刻只能谈一个男朋友.但是呢现实中,有钱,长得还帅,还巨能舔,同时满足这三点,现实中基本不存在.
于是你为了满足自己的这些要求,同时谈了三个男朋友:
A:有钱的 B:长得帅的 C:比较会舔的
因此,一个时间管理大师就横空出世了,你需要合理安排自己的时间,避免同一时刻,这三人碰面(G了).
这时候你首先要做的事情就是给自己排一个时间表:
宏观上看起来,你是同时谈了三个男朋友.
微观上看起来,同一时刻,你只是和一个男朋友在一起.
显然这就是并发,规划时间表的过程,也就是“调度”的过程.
站在上面的角度我们再来看看PCB中的进程调度属性:
1.状态
正常情况下,A B C三个人你都能随叫随到->他们都是就绪状态
假设A要出差一个月(赚钱去了)就可以认为A现在是阻塞状态.
因此处于这样状态的进程就暂时不进行调度(暂时不把这个A给排到时间表上).
2.优先级
在给A B C排时间表的时候,比如:就会优先给B排,其次给A排,最后给C排.
周一到周三,都和B甜蜜蜜的在一起.
周四周五,都和A甜蜜蜜的在一起.
周六,和C在一起.
周天给自己休息一天.
3.记账信息
如果长此以往,和C在一起的时间太少了,C对你的好感度就会降低,舔的也不够卖力了.
这时候你翻开你的时间表发现给C排的太少了,接下来就适当给点甜头.(舔狗不得house!!!,别人给点笑脸就灿烂了)
4.上下文
作为手握三位男朋友的你,把每周的时间都排的很紧,并且要随时转换角色,渐渐的有一天你就不小心串台了,比如:答应A的事情却给B做了,C过生日你却给A送了生日礼物.
为了区分,你养成记录日记的好习惯,把每次约会的重要信息都记录下来,下次和他们见面就能够对上号,哪怕时间长你也能查到.