1. 优先权调度算法 为了照顾紧迫型进程获得优先处理,引入了优先权调度算法。它从就绪队列中选择一个优先权最高的进程,让其获得处理器并执行。这时,又进一步把该算法分为两种方式:
1)非抢占式优先权调度算法 在这种方式下,系统一旦把处理器分配给就绪队列中优先权最高的进程后,该进程就占有处理器一直运行下去,直到该进程完成或因发生事件而阻塞,才退出处理器。系统这时才能将处理器分配给另一个优先权高的进程。这种方式实际上是每次将处理器分配给当前就绪队列中优先权最高的进程。它常用于批处理系统中,也可用于某些对时间要求不严格的实时系统中。
2)抢占式优先权调度算法 在这种方式下,系统同样把处理器分配给当前就绪队列中优先权最高的进程,使之执行。但在其执行期间,仍然会不断有新的就绪进程进入就绪队列,如果出现某个进程,其优先权比当前正在执行的进程的优先权还高时,进程调度程序就会立即暂停当前进程的执行,而将 处理器收回,并将处理器分配给新出现的优先权更高的进程,让其执行。这种方式实际上永 远都是系统中优先权最高的进程占用处理器执行。因此,它能更好地满足紧迫进程的要求, 故常用于要求比较严格的实时系统中,以及对性能要求较高的批处理和分时系统中。
对于优先权调度算法,其关键在于是采用静态优先权,还是动态优先权,以及如何确定 进程的优先权。
1) 静态优先权 静态优先权是在创建进程时确定的,并且规定它在进程的整个运行期间保持不变。一般来说,优先权是利用某个范围内的一个整数来表示的,如 0~7,或 0~255 中的某个整数, 所以又称为优先数。在使用时,有的系统用“0”表示最高优先权,数值越大优先权越小, 而有的系统则恰恰相反。
2) 动态优先权 动态优先权要配合抢占调度方式使用,它是指在创建进程时所赋予的优先权,可以随着进程的推进而发生改变,以便获得更好的调度性能。在就绪队列中等待调度的进程,可以随 着其等待时间的增加,其优先权也以某个速率增加。因此,对于优先权初值很低的进程,在 等待足够长的时间后,其优先权也可能升为最高,从而获得调度,占用处理器并执行。同样 规定正在执行的进程,其优先权将随着执行时间的增加而逐渐降低,使其优先权可能不再是 最高,从而暂停其执行,将处理器回收并分配给其他优先权更高的进程。这种方式能防止一 个长进程长期占用处理器的现象。
程序示例:
1. 本程序用两种算法对五个进程进行调度,每个进程可有三种状态,并假设初始状态为就 绪状态。
2. 为了便于处理,程序中的某进程运行时间以时间片为单位计算。各进程的优先数或轮转 时间数以及进程需运行的时间片数的初始值均由用户给定。
3. 在优先数算法中,优先数可以先取值为 50,进程每执行一次,优先数减 3,CPU 时间片 数加 1,进程还需要的时间片数减 1。
#include<stdio.h>
#include <dos.h>
#include<stdlib.h>
#include<conio.h>
#include<iostream>
using namespace std;
#include<windows.h>
#define P_NUM 5 //进程数
#define P_TIME 50 //优先数预先取值为50
enum state{
ready, execute, block, finish
};//定义进程状态
struct pcb{
char name[4]; //进程名
int priority; //优先权
int cputime; //CPU 运行时间
int needtime; //进程运行所需时间
int count; //进程执行次数
int round; //时间片轮转轮次
state process; //进程状态
pcb * next;
}; //定义进程 PCB
pcb * get_process(){
pcb *q;
pcb *t;//指向当前就绪进程
pcb *p;//一个指针指向5个进程排成的就绪队列的第一个进程
int i=0;
cout<<"input name and time"<<endl;
while (i<P_NUM)
{
q = (struct pcb *)malloc(sizeof(pcb));
cin>>q->name;//进程名称
cin>>q->needtime;//进程运行所需时间
q->cputime=0;//初始cpu运行时间为0
q->priority=P_TIME-q->needtime;//初始优先级: 50-所需 CPU 时间片数
q->process=ready;//设置进程状态为就绪状态
q->next=NULL;
if (i==0){
p=q;
t=q;
}
else{
t->next=q; //创建就绪进程队列
t=q;
}
i++;
} //while
return p;
} //输入模拟测试的进程名和执行所需时间,初始设置可模拟 5 个进程的调度
void display(pcb *p){
cout<<"name"<<" "<<"cputime"<<" "<<"needtime"<<" "<<"priority"<<" "<<"state"<<endl;
while(p){
cout<<p->name;
cout<<" ";
cout<<p->cputime;
cout<<" ";
cout<<p->needtime;
cout<<" ";
cout<<p->priority;
cout<<" ";
switch(p->process){
case ready:cout<<"ready"<<endl;break;
case execute:cout<<"execute"<<endl;break;
case block:cout<<"block"<<endl;break;
case finish:cout<<"finish"<<endl;break;
}
p=p->next;
}
} //显示模拟结果,包含进程名、CPU 时间、运行所需时间以及优先级
int process_finish(pcb *q){
int bl=1;
//循环判断,从第一个开始,一旦找到一个所需时间不为0的,停止循环,返回。
while(bl&&q)
{
bl = bl && q->needtime == 0;
q=q->next;
}
return bl;
} //结束进程,即将队列中各进程的所需时间设置为 0
void cpuexe(pcb *q){
pcb *t=q;
int tp=0;
while(q)
{
if (q->process != finish)
{
q->process=ready;
if(q->needtime==0){
q->process=finish;
}
}
//循环选择优先级最高的进程
if(tp < q->priority && q->process != finish){
tp = q->priority;//第一次循环获取第一个进程的优先级数
t = q;
}
q=q->next;
}
if(t->needtime!=0){
t->priority-=3;//进程每执行一次,优先数减 3
t->needtime--;//进程还需要的时间片数减 1
t->process=execute;//状态变为执行
t->cputime++;//CPU 时间片 数加 1
}
} //选择某一进程,给它分配 CPU
//计算进程优先级
void priority_cal(){
pcb * p;
system("cls");
//clrscr();
p=get_process();//获取就绪进程队列首地址
int cpu=0;
system("cls");
//clrscr();
while(!process_finish(p)){
cpu++;
cout<<"cputime:"<<cpu<<endl;
cpuexe(p);
display(p);
Sleep(2);
//system("cls");
//clrscr();
}
printf("All processes have finished,press any key to exit");
getch();
}
void display_menu(){
cout<<"CHOOSE THE ALGORITHM:"<<endl;
cout<<"1 PRIORITY"<<endl;
cout<<"2 ROUNDROBIN"<<endl;
cout<<"8 EXIT"<<endl;
} //显示调s度算法菜单,可供用户选择优先权调度算法和时间片轮转调度算法
int main(){
display_menu();//显示菜单
int k;
scanf("%d",&k);
while(k!=8)
{
switch(k)
{
case 1:priority_cal();break;
case 2:round_cal();break;
}
if(k==1||k==2)
break;
else
{
system("cls");
display_menu();
scanf("%d",&k);
}
}
}
代码分析:
程序执行流程如下: