进程调度算法
FCFS
先来先服务(first-come first-served, FCFS)的调度算法,是按照进程到达的先后次序进行调度,或者说它是优先考虑在就绪队列中等待时间最长的进程,而不管该进程所需执行的时间长短
SPF
短进程优先(short process first, SPF)的调度算法,是以进程所要求的运行时间长短来衡量优先级,时间越短,其优先级越高
缺点
- 必须预知进程的运行时间
- 长进程周转时间会明显增长
- 无法实现人机交互
- 不能保证紧迫性作业能即时处理
PSA
优先级调度算法(priority-scheduling-algorithm, PSA),FCFS与SPF均不能对紧迫性进程进行处理,而PSA则是基于进程的紧迫程度,由外部赋予进程相应的优先级,调度算法是根据该优先级进行调度的。这个分配可以在进程创建时确立,整个运行期间不再改变,这种优先级成为静态优先级;动态优先级是指在进程创建的时候先赋予一个优先级,然后其值随进程的推进或等待时间的增加而改变,以获得更好的调度性能,比如下面的HRRN。
当然,当CPU正在执行一个进程,此时另一个高优先级的进程进入就绪队列,如果此时CPU放弃当下进程,去执行高优先级进程,这种方式就成为抢占式优先级调度算法;若不进行抢占,而是等到当前进程执行完再执行高优先级进程,就被称为非抢占优先级调度算法
HRRN
高响应比优先调度算法(Highest Response Ratio Next, HRRN)是结合了FCFS和SPF,平衡了进程的等待时间的进程的运行时间,从而改善了处理机的调度性能
可见该优先级是动态变化的,长进程的优先级可以随着等待时间的增加而提高,当其等待时间足够长时,也可以获得处理机。但同时也存在一个缺点,每次进行调度之前都要计算响应比,这无疑增加了系统开销
RR
基于时间片的轮转(round robin,RR)调度算法是先根据FCFS策略将就绪进程排成一个就绪队列,每隔一定时间产生一次中断,激活系统中的进程调度程序完成一次调度。先将CPU分配给队首进程,当该进程时间片消耗尽或者运行完毕再将CPU分配给新的队首进程,未执行完的进程再插到队尾继续等待执行。
时间片的选择:
- 时间片太小,意味着会频繁的执行进程调度和上下文切换,增加系统开销
- 时间片过长,能让每一个进程都能在一个时间片内完成,RR便退化成为FCFS算法
- 一个较为可取的时间片大小是略大于一次典型的交互所需要的时间,使大多数交互式进程能在一个时间片内完成,从而获得很小的响应时间
多队列调度算法
在多处理机系统中,一个就绪队列无法满足不同用户对进程调度策略的不同要求,所以将进程的就绪队列从一个拆分为若干个,将不同类型或性质的进程固定在不通过的就绪队列,不同的就绪队列采用不同的调度算法,一个就绪队列中的进程可以设置不同的优先级,不同的就绪队列本身也可以设置不同的优先级
多级反馈队列调度算法
多级反馈队列调度算法特点在于未指明进程的长度时,依然能高效的实现进程调度
- 在系统中设置多个就绪队列,并为每个队列赋予不同的优先级。第一个队列的优先级最高,第二个次之,其余队列的优先级逐个降低。该算法为不同队列中的进程所赋予的执行时间片的大小也各不相同,在优先级愈高的队列中,其时间片就愈小
- 每个队列都采取FCFS算法,若一个进程进入到第一个队列执行,时间片内完成便撤离系统,否则调度进程到第二队列末尾等待,若在第二队列仍未完成,继续下调…当该进程被下调到第N队列,在该队列采用RR方式运行
- 调度程序首先调度最高优先级队列中的进程运行,仅当第一队列空闲时才调度第二队列中的进程运行
PCB(进程控制块)
不难发现,在上面进程的调度算法中,不管是优先级调度算法优先级的确定,还是抢占式优先级调度算法中进程上下文的切换,都需要进程的相关信息
操作系统管理进程,实则是将进程的有效信息提取出来然后通过管理这些信息来管理进程,而所有的进程信息被存放在一个叫做进程控制块的数据结构中(可以理解为进程属性的集合),即PCB(进程控制块)
每个进程在内核中都有一个进程控制块(PCB)来维护进程相关的信息,Linux内核的进程控制块是task_struct结构体
下面是两篇大佬关于task_struct各字段详细介绍的博客:
僵尸进程&孤儿进程
僵尸进程
进程退出的时候都会向它的父进程发送退出状态码,如果父进程正常读取了这个退出状态码,子进程退出成功;而一旦子进程的退出状态码没有被父进程读取,父进程这时候还在执行,子进程将会进入僵尸状态
通过下面这段代码来造成僵尸进程:
一个进程创建了子进程,启动后子进程睡眠五秒后退出,此时父进程正处于睡眠状态,无法对子进程的退出状态码进行读取,在父进程睡眠的这段时间里,子进程就处于僵尸态
孤儿进程
如果一个进程的父进程先于自己退出,该进程就被称为孤儿进程
用下面这段代码来制造孤儿进程:
可以发现,父进程退出后,该进程由前端转到了后台
环境变量
环境变量一般是指在操作系统中用来指定操作系统运行环境的一些参数
环境变量相关的命令
- echo $NAME:NAME表示指定的环境变量名称
- export:设置一个新的环境变量
- env:显示所有的环境变量
- set:显示本地定义的shell变量和环境变量
- unset:清除环境变量
环境变量的属性
- getenv(“NAME”):用户获得环境变量NAME的内容
- putenv(“NAME”):putenv()用来改变或增加环境变量的内容。参数envvar的格式为envvar=value,如果该环境变量原先存在,则变量内容会依参数envvar改变,否则此参数内容会成为新的环境变量
全局变量一般具有全局属性,可以被子进程继承下去
但是在每一个终端上打开的shell都是独立的,在一个shell中定义的环境变量,不会在其他shell中有效