操作系统实习报告

处理器调度算法的实现

1先来先服务调度算法
1.1题目内容
设计程序模拟单处理机系统中的进程调度算法,在先来先服务算法,时间片轮转调度算法和优先数调度算法三种算法中选择一种。
1.2题目要求
(1)每个进程由一个进程控制快(PCB)表示。进程控制块可以包含如下信息:进程名,优先数,到达时间,需要运行时间,已用CPU时间,进程状态等。
(2)进程的优先数及需要运行时间可以事先人为指定(也可由随机数产生)。进程的到达时间为进程的输入时间。
(3)进程的运行时间以时间片为单位进行计算。
(4)每个进程的状态可以是就绪W(Wait),运行R(Run)或者完成F(Finish)3个状态之一。
(5)按照作业/进程进入队列的先后顺序进行挑选,先进入的将先进性后续步骤处理。
1.3设计思想
该算法按照进程到达时间先后顺序执行,先到达的先执行。
1.4算法分析
(1)定义PCB结构体;
(2)P_input()输入函数;
(3)P_output()输出函数;
(4)sort()函数排序;
(5)main()主函数。
1.5核心代码
#include
#include
using namespace std;
/结构体/
struct PCB
{
char name[10]; //进程号
int arrivalTime; //到达时间
int serviceTime; //服务时间
int startTime; //开始时间
int finishTime; //完成时间
int zzTime; //周转时间
double dqzzTime; //带权周转时间
};
/输入函数/
void P_input(int n,struct PCB pr[])
{ //输入进程号,到达时间及服务时间
printf(“请依次输入进程号、到达时间、服务时间:\nFor example:a 1 5\n”);
for (int i=0 ; i scanf("%s %d %d",&pr[i].name, &pr[i].arrivalTime,&pr[i].serviceTime);
}
/输出函数/
void P_output(int n,struct PCB pro[])
{ //输出进程号,到达时间,服务时间,开始时间,完成时间,周转时间,带权周转时间
printf(“进程号 到达时间 服务时间 开始时间 完成时间 周转时间 带权周转时间\n”);
printf("------------------------------------------------------------------------\n");
for (int i=0 ; i printf("%s%8d%10d%10d%10d%10d%13.2f\n",
pro[i].name, pro[i].arrivalTime,pro[i].serviceTime,pro[i].startTime,
pro[i].finishTime,pro[i].zzTime,pro[i].dqzzTime);
printf("------------------------------------------------------------------------\n");
}

/排序,将个进程到达时间进行升序排序/
void sort(int n,struct PCB pro[])
{
/初始化/
pro[0].startTime=0;
pro[0].finishTime=0;
pro[0].zzTime=0;
pro[0].dqzzTime=0;
//对所有进程的到达时间进行排序
struct PCB t;
for (int i=0 ; i for (int j=0 ; j if (pro[i].arrivalTime < pro[j].arrivalTime)
{ //此进程到达时间小于下一进程到达时间
t = pro[i];
pro[i] = pro[j];
pro[j] = t;
}
for(int k=0 ; k { //当前时刻判断下一个进程是否到达
if(k==0)
{ //未到达
pro[k].startTime=pro[k].arrivalTime; //把下一进程的到达时间赋给开始时间
pro[k].finishTime=pro[k].startTime+pro[k].serviceTime; //计算完成时间=开始时间+服务时间
}
else //下一进程已到达
{
pro[k].startTime=pro[k-1].finishTime; //此进程的完成时间即为下一进程的开始时间
pro[k].finishTime=pro[k].startTime+pro[k].serviceTime;
}
pro[k].zzTime=pro[k].finishTime-pro[k].arrivalTime; //计算周转时间=完成时间-到达时间
pro[k].dqzzTime=pro[k].zzTime/pro[k].serviceTime; //带权周转时间=周转时间/服务时间
}
}
/主函数/
void main()
{
struct PCB pr[100];
struct PCB pro[100];
int n;
printf(“请输入进程个数:\n”);
scanf("%d", &n);
P_input(n,pro);
pro[100]=pr[100];
sort(n,pro);
P_output(n,pro);

}

1.6程序流程图
操作系统实习报告_第1张图片
1.7测试数据或截图
操作系统实习报告_第2张图片
2 时间片轮转调度算法
2.1题目内容
设计程序模拟单处理机系统中的进程调度算法,在先来先服务算法,时间片轮转调度算法和优先数调度算法三种算法中选择一种。
2.2题目要求
(1)每个进程由一个进程控制快(PCB)表示。进程控制块可以包含如下信息:进程名,优先数,到达时间,需要运行时间,已用CPU时间,进程状态等。
(2)进程的优先数及需要运行时间可以事先人为指定(也可由随机数产生)。进程的到达时间为进程的输入时间。
(3)进程的运行时间以时间片为单位进行计算。
(4)每个进程的状态可以是就绪W(Wait),运行R(Run)或者完成F(Finish)3个状态之一。
(5)按照作业/进程进入队列的先后顺序进行挑选,先进入的将先进性后续步骤处理。
2.3设计思想
(1)该算法按照先来先服务执行进程,根据进程到达时间的先后顺序让进程在所给定的时间片内运行,运行完成后调度下一个进程运行。
(2)时间片轮转调度属于抢占式调度,适用于分时系统。
2.4算法分析
(1)结构体进程控制块
(2)P_input()输入函数
(3)sort()函数对进程到达时间排序
(4)RR()函数执行轮转调度算法
(5)main()主函数
2.5核心代码
#include
#define N 50 //定义最大进程数为50
struct PCB
{
char name[10]; //进程名
int arrivaltime; //到达时间
int servicetime; //服务时间
int finishtime; //完成时间
int zztime; //周转时间
double dqzztime; //带权周转时间
int sign; //完成进程标志
int st1; //剩余服务时间
}p[N]; //进程控制块数组
//输入函数
void P_input(int n)
{ //输入进程名,到达时间,服务时间
printf(“请依次输入进程名,到达时间,服务时间:\n”);
for(int i=0;i {
p[i].sign=0;
scanf("%s %d %d",&p[i].name,&p[i].arrivaltime,&p[i].servicetime);
p[i].st1=p[i].servicetime;
}
}
//排序
void sort(int n)
{
struct PCB t;
for(int i=0;i for(int j=i;j {
if(p[i].arrivaltime >p[j].arrivaltime )
{
t=p[j];
p[j]=p[i];
p[i]=t;
}
}
}
void RR(int n)
{
int T; //定义时间片
printf(“请输入时间片:\n”);
scanf("%d",&T);
P_input(n); //调用输入函数
sort(n); //调用sort()排序
int time=p[0].arrivaltime; //time为当前时间,赋初值
int flag=1; //标志就绪队列中有进程
int sum=0; //记录完成的进程数
printf(“进程名 到达时间 服务时间 开始时间 完成时间 周转时间 带权周转时间\n”);
while(sum {
flag=0; //就绪队列没有进程
for(int i=0;i {
if(p[i].sign==1) //已完成进程
continue;
else //未完成的进程
{

			if(p[i].st1<=T&&time>=p[i].arrivaltime)//还需服务的时间少于等于一个时间片 
			{
	 	      flag=1;  //把进程加入到就绪队列中
	       	  time+=p[i].st1;
	 	      p[i].sign=1; //此进程完成
	          p[i].finishtime=time;
              p[i].zztime=p[i].finishtime-p[i].arrivaltime;  //计算周转时间
			  p[i].dqzztime=p[i].zztime/p[i].servicetime;   //计算带权周转时间
	 	      printf("%s%8d%10d%10d%10d%10d%13.2f\n",p[i].name,p[i].arrivaltime,p[i].servicetime,
				  time-p[i].st1,time,p[i].zztime,p[i].dqzztime);  //输出进程信息
			}		 	    
			else if(p[i].st1>T&&time>=p[i].arrivaltime)//还需服务时间至少大于一个时间片 
			{
	 		  flag=1;  //把进程加入到就绪队列中
	 		  time+=T;
			  p[i].st1-=T;
              p[i].zztime=p[i].finishtime-p[i].arrivaltime; //计算周转时间
			  p[i].dqzztime=p[i].zztime/p[i].servicetime;  //计算带权周转时间
			  printf("%s%8d%10d%10d%10d%10d%13.2f\n",p[i].name,p[i].arrivaltime,p[i].servicetime,
				  time-T,time,p[i].zztime,p[i].dqzztime); // 输出进程信息
			} 
	    	if(p[i].sign==1)
 		       sum++;     //一个进程执行完就+1
		}
	 }

} 

}
void main()
{
int n;
printf(“请输入总进程数:\n”);
scanf("%d",&n);
RR(n);
}

2.6程序流程图
操作系统实习报告_第3张图片
2.7测试数据或截图
操作系统实习报告_第4张图片
3优先数调度算法
3.1题目内容
设计程序模拟单处理机系统中的进程调度算法,在先来先服务算法,时间片轮转调度算法和优先数调度算法三种算法中选择一种。
3.2题目要求
(1)每个进程由一个进程控制快(PCB)表示。进程控制块可以包含如下信息:进程名,优先数,需要运行时间,进程状态等。
(2)进程的优先数及需要运行时间可以事先人为指定(也可由随机数产生)。
(3)每个进程的状态可以是就绪W(Wait),运行R(Run)或者完成F(Finish)3个状态之一。
(5)按照作业/进程进入队列的先后顺序进行挑选,先进入的将先进行后续步骤处理。
3.3设计思想
采用抢占式优先数算法,在运行过程中允许具有更高优先级的就绪进程进入CPU运行。
3.4算法分析
(1)定义结构体进程控制块
(2)P_input()输入函数
(3)P_output()输出函数
(4)max_pri()函数找出就绪态中的最大优先数进程
(5)run()函数为优先数调度算法
(6)main()主函数
3.5核心代码
#include
#define num 5 //假设系统中进程个数为5

/结构体/
struct PCB
{
char name[10];//进程名
int runtime;//运行时间
int priority;//优先数
char state;//状态,两状态:W-就绪;F-运行;F-结束。
};
struct PCB A[num];//定义进程控制块数组

//输入函数
void P_input()
{ //输入进程名,运行时间和优先数
printf(“请输入PCB的进程名,运行时间,优先数:\nFor example: p 2 9\n”);
for(int i=0;i {
scanf("%s %d %d",&A[i].name,&A[i].runtime,&A[i].priority);
A[i].state=‘W’;//初始状态都设为就绪
getchar();
}
}
//输出函数
void P_output()
{ //输出进程号,运行时间,优先数,状态
printf("\n进程号 运行时间 优先数 状态\n");
printf("------------------------------\n");
for(int i=0;i printf("%s %7d%9d\t%s\n",&A[i].name,A[i].runtime,A[i].priority,&A[i].state);
printf("------------------------------\n");
}

//进程在就绪状态时找出最大优先数进程(返回值为最大优先数编号)
int max_pri()
{
int max=-1;//max为最大优先数
int m;//m为最大优先数进程的编号
for(int i=0;i { //进程在就绪状态时找出最大优先数
if(A[i].state==‘R’) //进程在运行状态
return -1;
else if((max {
max=A[i].priority;
m=i; //把最大优先数对应的编号赋给m
}
}
//确保最大优先数进程还没结束运行
if(A[m].state==‘F’) //最大优先数进程已结束运行
return -1;
else //最大优先数进程还没结束运行
return m; //返回值为最大优先数编号
}

//优先数调度算法
void run()
{
int max_time=-1,m=0;
int sum=0;//sum为程序总运行次数
for(int i=0;i sum+=A[i].runtime;
printf("\n初始时各进程信息:\n");
P_output();
getchar();
for(int j=0;j {
//当程序正在运行时
while(max_pri()!=-1) //max_pri()为找出最大优先数进程函数,返回最大值对应的编号m
{
if(A[max_pri()].priority!=0)
A[max_pri()].state=‘R’; //由就绪转为运行态
else
{ //当优先级降为0,进程还没运行完时
for(i=0;i if(max_time {
max_time=A[i].runtime;
m=i; //返回对应的编号
}
max_time=-1;
A[m].state=‘R’; //状态转为运行态
}
}

    //判断程序状态(对优先数和运行时间操作) 
    for(int i=0;i0)     //优先数>0
               A[i].priority--;  //每运行一次优先数-1
            A[i].runtime--;   //每运行一次运行时间-1
        }
        if(A[i].runtime==0)  //运行时间完
			A[i].state='F';   //进程状态转为完成状态
        else     //运行时间没完
			A[i].state='W';   //进程状态转为就绪状态
    } 
    P_output();
    getchar();
}    

}

int main()
{
P_input();//输入函数
run();//优先数调度算法
return 0;
}
3.6程序流程图
操作系统实习报告_第5张图片
3.7测试数据或截图
操作系统实习报告_第6张图片
操作系统实习报告_第7张图片
操作系统实习报告_第8张图片
操作系统实习报告_第9张图片
4心得体会
通过这次实习,使我更加了解进程的概念,进一步掌握进程状态的转变,进程调度的策略以及对系统性能的评价方法。也是这次实验,我对先来先服务算法,时间片轮转调度算法,优先级调度算法有了更深的理解并对算法有了一定的掌握。
(1)先来先服务算法是一种最简单的算法,可以应用于高级调度(作业调度)也可以应用于低级调度(进程调度)。高级调度时,FCFS调度算法按照作业进入后备作业队列的先后顺序选择作业进入内存,然后为选中的作业创建进程并分配该作业所需资源。低级调度时,FCFS调度算法每次从内存的进程/线程就绪队列中选择一个最先进入的进程/线程,然后由进程/线程调度程序将CPU分配给它并使其运行。FCFS调度算法是一种非抢占式调度算法,当某进程/线程占用了CPU后就一直运行,直到其运行结束才放弃CPU,或在运行中因发生某等待事件被阻塞而放弃CPU。
(2)时间片轮转调度算法主要用于低级调度,调度方式实际上是一种基于时钟的抢占式调度算法。在采用时间片轮转调度算法的系统中,进程/线程就绪队列按到达时间的先后次序进行排队,按照先来先服务原则,选择就绪队列中的第一个进程/线程,将CPU分配给它执行。进程/线程每次使用一个时间片,当它用完规定的时间片时必须放弃CPU的使用权。这时,进程/线程调度程序又将CPU分配给当前就绪队列的第一个进程/线程,而放弃CPU的进程/线程,则回到就绪队列的队尾,等待再次调度。故只要是处于就绪队列的进程/线程,按时间片轮转法调度将迟早会获得CPU而的得到运行,并不会发生无限期等待的情况。
(3)优先级调度算法既可以应用于高级调度(作业调度)也可以应用于低级调度(进程调度),还可用于实时系统。高级调度时,优先数调度算法每次从后备作业队列中选择优先级最高的作业调入内存,为其分配相应的资源并创建进程放入到进程就绪队列中。低级调度时,优先级调度算法每次从进程就绪队列中选择优先级最高的进程为其分配CPU而投入运行。如果有多个优先级最高的作业/进程,则可结合先来先服务或短作业/短进程优先调度策略。
这次实习也让我明白:学习操作系统和学习其他知识一样,在学习过程中都会遇到困难与瓶颈期,关键在于不放弃。

最后,我想对阅读这篇博客的读者说:我的博客内容有许多不足,希望多提建议。

你可能感兴趣的:(操作系统)