AtlasHR 2017-09-05
当计算机在引入多道程序时,出现了临界资源竞争的情况,为了刻画和解决程序间的这种制约关系,提出了进程的概念,用以改善资源的利用率,提高程序的吞吐量。
/*全局变量nr_task动态记录进程数*/ struct task_sturct *task[NR_TASK]={&init_task};
运行状态进程的PCB同样用结构体指针数组表示:
current_set[];
struct task_struct{ ... unsigned short uid; int pid; ... volatile long state; long prority; unsigned long rt_protity; long counter; unsigned long policy; ... struct task_struct *next_task, *prev_task; struct task_struct *next_run, *prev_run; struct task+struct *p_opptr, *pptr, *p_cptr, *pysptr, *p_ptr; ... };
数据成员说明:
uid:用户标识;
pid:进程标识;
state:进程状态标识;
1)可运行状态
2)可中断阻塞状态
3)不可中断阻塞状态
4)僵死状态
5)暂停状态
6)交换状态
protity:进程优先级;
counter:优先级计数器,用于进程轮转调度算法;
policy:进程调度策略;
next_task,prev_task:PCB双向链表指针;
p_opptr ...:指明进程家族间的关系,分别为祖父进程,父进程,子进程,以及新老进程指针;
谦让度:标识进程之间资源竞争能力,高谦让度的进程,资源竞争能力弱。负值或0表示最高优先级,对其他进程不谦让。谦让度的值一般为:-20~19;当前硬件发展速度非常快,一般我们是不设置进程优先级的,除非有进程失控而疯狂的抢占资源;
在创建进程时,nice可以为进程设置谦让值,但进程优先级的值为父进程shell优先级的值与nice所指定的谦让度相加的结果。即,利用nice指定的值是一个增量,而不是优先级的绝对值。
运行 a.out 程序,并为它指定谦让度增量为5:
nice -n 5 a.out &
利用renice来更改谦让度:
renice 谦让度 PID
程序使用cpu的三种模式:I/O密集型、计算密集型和平衡型。对于I/O密集型程序,响应时间非常重要,响应时间不及时,和可能丢失数据;对于计算密集型程序,cpu的周转时间非常重要;对于平衡型程序,协调响应和cpu周转的工作最重要。
进程周转时间:等待进入内存的时间,在就绪队列中等待的时间,在 CPU中执行的时间和I/O操作的时间的总和。
FCFS(frist come first serve),也叫FIFO算法,先来先执行。短任务执行可能会非常慢,因为前面的进程可能占用很长时间,造成平均响应时间过长。
目的是改善短程序响应时间长的问题。方法是周期性的对进程进行切换。该算法最关键的时间片的选择,时间片过长和FIFO算法区别不大,时间片过短,进程频繁切换的开销大于执行程序的开销,系统效率降低。
STCF算法全称:short time to complete frist。核心是每个进程都有优先级,短进程的优先级要高于长进程的优先级。STCF算法分为:非抢占式和抢占式两类。非抢占式就是让已经在cpu上运行的程序执行到结束或者阻塞,然后在就绪队列中选择执行时间最短的程序来执行。而抢占式是,每当有新进程进入就绪队列时,都会去判断当前运行进程和新进程的执行时间长短,选择执行时间短的进程运行,及永远保证cpu运行的是所有进程中执行时间最短的进程。该算法有个非常明显的缺点:长任务进程无法执行。还有该算法的关键点是如何预测进程所需的执行时间。
解决了STCF算法中长任务进程饥饿的问题,而暴露出的短任务会饥饿的问题,可以通过动态调整优先级来解决。实际上动态调整优先级(称为权值)+ 时间片轮转的策略正是Linux系统进程调度的策略之一的分时调度策略,调度过程如下:
(1) 创建任务指定采用分时调度策略,指定优先级nice的值(-20~19) (2) 依据nice的值确定在cpu上的执行时间 (3) 如果没有等待资源,则将该任务加入就绪队列中 (4) 调度程序遍历就绪队列,通过对动态优先级的计算,选择计算结果最 大的去执行。当时间片用完时或进程主动放弃cpu时,该任务就重新放回就 绪队列队尾或等待队列中。 (5) 调度程序重新按照(4)的方式调度进程。 (6) 当调度程序发现所有就绪队列中的进程的权值都不大于0时,重复(2) 的过程
现代OS通常都会采用混合调度算法。如:将不同的进程分为几个大类,每个大类有不同的优先级,不同大类的进程调度取决于大类的优先级,同一个大类的进程调度采用时间片轮转算法来实现。