操作系统:进程调度
衡量调度的标准
不同的调度算法有各自不同的属性,侧重点是不一样的.
调度准则用于比较不同的调度算法.根据不同的调度准则进行比较,则得出的比较结果是不同的.
- CPU利用率:使CPU尽可能的忙碌
- 吞吐量(Throughput):单位时间内运行完的进程数
- 周转时间(Turnaround time):从提交到运行结束的全部时间
- 等待时间:进程在就绪队列中等待调度的时间总和
- 响应时间:从进程提出请求到首次被响应的时间段[在分时系统环境下不是输出完结果的时间]
- 优化标准:最大的CPU利用率、最大的吞吐量、最短的周转时间、最短的等待时间、最短的响应时间。
题目
1、本程序可选用优先数法或简单轮转法对五个进程进行调度。每个进程处于运行R(run)、就绪W(wait)和完成F(finish)三种状态之一,并假定起始状态都是就绪状态W。
为了便于处理,程序中进程的运行时间以时间片为单位计算。各进程的优先数或轮转时间片数、以及进程需要运行的时间片数,均由伪随机数发生器产生。
进程控制块结构如表2-1所示:
进程控制块链结构如图2-1所示:
图2-1 进程控制块链结构
其中:RUN—当前运行进程指针;
HEAD—进程就绪链链首指针;
TAIL—进程就绪链链尾指针。
2. 算法与框图 程序框图如图2-2所示。
(1)优先数法。 进程就绪链按优先数大小从大到小排列,链首进程首先投入运行。每过一个时间片,运行进程所需运行的时间片数减1,说明它已运行了一个时间片,优先数也减3。理由是该进程如果在一个时间片中完成不了,优先级应降低一级。接着比较现行进程和就绪链链首进程的优先数,如果仍是现行进程高或者相同,就让现行进程继续运行,否则,调度就绪链链首进程投入运行。原运行进程再按其优先数大小插入就绪链,且改变它们对应的进程状态,直至所有进程都运行完各自的时间片数。
(2)简单轮转法。 进程就绪链按各进程进入的先后次序排列,链首进程首先投入运行。进程每次占用处理机的轮转时间按其重要程度登入进程控制块中的轮转时间片数记录项(相应于优先数法的优先数记录项位置)。每过一个时间片,运行进程占用处理机的时间片数加1,然后比较占用处理机的时间片数是否与该进程的轮转时间片数相等,若相等说明已到达轮转时间,应将现运行进程排到就绪链末尾,调度链首进程占用处理机,且改变它们的进程状态,直至所有进程完成各自的时间片。
注:基于实验报告的修改
#include <stdio.h>
#include <stdlib.h>
#define furthest 5
/*
author:haobo
time:20.12.7
*/
struct process { /*PCB STRUCTURE*/
int id; //进程id
int priority; //优先级
int cputime; //现运行时间
int alltime; //总运行时间
char state; //状态
int next; //指向下一个
}prochain[furthest+1];//进程队列
int procnum;
int rand();
int algo;
int run,head,tail,j;
void insert2();
void insert(int q);
void print();//process
void init();
void prisch();
void timesch();
int main() { /*MAIN PROGRAM*/
agan:
/*
两种算法
1-->调度简单轮转法
2-->优先数法
*/
printf("type the algorithm is (1:RR,2:PRIO):");
scanf("%d",&algo);
if (algo==2) {
printf("output of priority.\n");
init();
prisch();
} else {
if (algo==1) {
printf("output of round robin.\n");
init();
timesch();
} else {
printf("try again,please\n");
goto agan;
}
}
for (j=1; j<=40; j++) {
printf("=");
}
printf("\n\n");
for (j=1; j<=40; j++) {
printf("=");
}
printf("\n\n");
printf("system finished\n");
getchar();//
}
void insert2() {
/*PUT A PROCESS ONTO THE TAIL OF THE QUEUE*/
//将进程插入到队列头部
prochain[tail].next=run;
tail=run;
prochain[run].next=0;
}
void insert(int q) {
/*INSERT A PROCESS*/
//插入一个进程
int p,s;
p=head;
s=prochain[head].next;
while((prochain[q].priority<prochain[s].priority)&&(s!=0)) {
p=s;
s=prochain[s].next;
}
prochain[p].next=q;
prochain[q].next=s;
}
void print(){
/*
PRINT THE RUNNING PROCESS,
WAITINGQUEUE AND PCB SEQUENCE LIST
*/
int k,p;
for (k=1; k<=40; k++)
printf("=");
printf("\nrunning proc. ");
printf("waiting queue.");
printf("\n %d ",prochain[run].id);
p=head;
while(p!=0) {
printf("%5d",p);
p=prochain[p].next;
}
printf("\n");
for (k=1; k<=40; k++)
printf("=");
printf("\n");
printf(" id ");
for (k=1; k<furthest+1; k++)
printf("%5d",prochain[k].id);
printf("\n");
printf("priority ");
for (k=1; k<furthest+1; k++)
printf("%5d",prochain[k].priority);
printf("\n");
printf("cputime ");
for (k=1; k<furthest+1; k++)
printf("%5d",prochain[k].cputime);
printf("\n");
printf("alltime ");
for (k=1; k<furthest+1; k++)
printf("%5d",prochain[k].alltime);
printf("\n");
printf("state ");
for (k=1; k<furthest+1; k++)
printf("%5c",prochain[k].state);
printf("\n");
printf("next ");
for (k=1; k<furthest+1; k++)
printf("%5d",prochain[k].next);
printf("\n");
}
void timesch() {
/*
THE PROCESS WITH RR ALRORITHM
简单轮转法
*/
while(run!=0) {
prochain[run].alltime-=1;
//prochain[run].priority-=3;
prochain[run].cputime+=1;
if(prochain[run].alltime==0) {
prochain[run].state='F';
prochain[run].next=0;
if(head!=0) {
run=head;
prochain[run].state='R';
head=prochain[head].next;
} else {
prochain[0].id=prochain[run].id;
run=0;
}
} else {
if((prochain[run].cputime==prochain[run].priority)&&(head!=0)) {
prochain[run].state='W';
//prochain[run].cputime=0;
insert2();
run=head;
prochain[run].state='R';
head=prochain[head].next;
}
}
print();
}
}
void init() {
/*CREATE A WAITING QUEUE*/
//wait进程
int i;
head=0;
if (algo==2) {
for (i=1; i<furthest+1; i++) {
//初始化进程表
//printf("%d\n furthest222",furthest);
prochain[i].id=i;
prochain[i].priority=(rand()+11)%41;//%5+1
prochain[i].cputime=0;
prochain[i].alltime=(rand()+1)%7+1;
prochain[i].state='W';
prochain[i].next=0;
if((prochain[i].priority<prochain[head].priority)&&(head!=0)){
insert(prochain[i].id);
}else {
prochain[i].next=head;
head= prochain[i].id;
}
}
} else {
for (i=1; i<furthest+1; i++) {
prochain[i].id=i;
prochain[i].priority=(rand()+1)%3+1;//%5+1
prochain[i].cputime=0;
prochain[i].alltime=(rand()+1)%7+1;
prochain[i].state='W';
prochain[i].next=(i+1)%(furthest+1);
}
head=1;
tail=furthest;
prochain[furthest].next=0;
}
run=head;
prochain[run].state='R';
head=prochain[head].next;
prochain[run].next=0;
print();
}
void prisch() {
/*
THE PROCESS WITH PRIO ALGORITHM
优先数
*/
while(run!=0) {
prochain[run].cputime+=1;
prochain[run].priority-=3;//
prochain[run].alltime-=1;
if(prochain[run].alltime==0) {
//此进程结束
prochain[run].state='F';
prochain[run].next=0;
if(head!=0) {
//若队列还有,切换
run=head;
prochain[run].state='R';
head=prochain[head].next;
} else {
prochain[0].id=prochain[run].id;
run=0;
}
} else {
if((prochain[run].priority<= prochain[head].priority)&&(head!=0)) {
//当前运行优先级低于链瘦时候
prochain[run].state='W';
insert(run);
run=head;
prochain[run].state='R';
head= prochain[head].next;
}
}
print();
}
}