2015年10月21日实验一 进程调度1.实验目的:通过对进程调度算法的模拟,进一步理解进程的基本概念,加深对进程运行状态和进程调度过程、调度算法的理解。
2.实验内容:(1)用C 语言(或其它语言,如Java )实现对N 个进程采用某种进程调度算法(如先来先服务调度、短作业优先调度、优先权调度、时间片轮转调度、多级反馈队列调度)的调度。
(2)为了清楚地观察每个进程的调度过程,程序应将每个进程的被调度情况显示出来。
(3)分析程序运行的结果,谈一下自己的收获。
3.设计实现: 1)流程图主流程图:choice!=1&&choice!=2c hoice==2c hoice==1YN开 始初始化参数 输入函数 输入chioce FCFS SJF输入有误,请重新输入!是否继续?结束输入函数流程图:请输入进程个数:NumNY i=0N i=0N先来先服务流程图:i=0NYNY开始Num>0&&Num<=100i <Num?输入进程 到达时间i++i <Num?输入进程 服务时间i++输入choice 选择算法结束开始 i <Num?进程到达?到达时间赋给NowTim服务时间赋给NowTim计算完成时间,周转时间(平均),带权周转时间(平均)输出结束短作业优先算法流程图:i =0Ni = 0开始计算第一次NowTime 和第一个进程的完成时间输出i <Num?进程到达?找出服务时间最短进计算完成时间,i++i <Num?计算(平均)周转时间 (平均)带权周转时间i++输出 结束2)详细设计本程序用C# 语言模拟了先来先服务,短作业优先两个调度算法,如下:环境:VS 2013using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace sjf_01{class Program{const int Max = 100;int[] ArrivalTime = new int[Max];//到达时间int[] ServiceTime = new int[Max];//服务时间int[] FinishTime = new int[Max];//完成时间int[] WholeTime = new int[Max];//周转时间double[] WeightWholeTime = new double[Max];//帯权周转时间double AverageWT_FCFS, AverageWT_SJF; //平均周转时间double AverageWWT_FCFS, AverageWWT_SJF;//平均帯权周转时间int[] ServiceTime_SJF = new int[Max];//在SJF算法中使用到int Num = 0; int NowTime = 0;//记录当前时间double SumWT = 0, SumWWT = 0;//SumWT用来计算总的周转时间,SumWWT用来计算总的帯权周转时间int i;int choice;//记录选择void FCFS(){for (i = 0; i < Num; i++){if (ArrivalTime[i] > NowTime)//假如进程到达的时间比现在已经运行的时间NowTime大,说明在NowTime时刻进程未到达{NowTime = ArrivalTime[i];//把进程的到达时间赋给NowTime}NowTime += ServiceTime[i];//把进程的服务时间加到NowTime上FinishTime[i] = NowTime;//计算完成时间WholeTime[i] = FinishTime[i] - ArrivalTime[i];//计算周转时间=完成时间-到达时间WeightWholeTime[i] = (double)WholeTime[i] / ServiceTime[i];//计算带权周转时间=周转时间/服务时间SumWT += WholeTime[i];//计算总的周转时间SumWWT += WeightWholeTime[i];//计算总的帯权周转时间}AverageWT_FCFS = SumWT / Num;//平均周转时间AverageWWT_FCFS=SumWWT/Num;//平均帯权周转时间for (i = 0; i < Num; i++)//依次输出结果{//Console.WriteLine("时刻{0} 进程{1} 开始运行完成时间{2} 周转时间{3} 带权周转时间{4}",FinishTime[i]-ServiceTime[i],i+1,FinishTime[i],WholeTime[i],WeightWholeTime[i]);Console.Write("时刻:{0} ", FinishTime[i] - ServiceTime[i]);Console.Write("进程:{0} ", i+1);Console.Write("开始运行 ");Console.Write("完成时间:{0} ", FinishTime[i]);Console.Write("周转时间:{0} ", WholeTime[i]);Console.Write("带权周转时间:{0} ", WeightWholeTime[i]);Console.WriteLine();}Console.WriteLine("平均周转时间{0},平均带权周转时间{1}",AverageWT_FCFS,AverageWWT_FCFS );}void SJF(){int min = 0;NowTime = ArrivalTime[0] + ServiceTime[0];//计算第一次的NowTImeFinishTime[0] = NowTime;//计算第一个进程的完成时间ServiceTime_SJF[0] = 1000;//赋初值Console.Write("时刻{0} 进程{1} 开始运行", FinishTime[0] - ServiceTime[0],1);int allin = 0, j, k;for (i = 1; i < Num; i++)//进入循环,从第二个到达的进程开始{k = 1; min = 0;if (allin == 0){j = 0;while (ArrivalTime[j] <= NowTime && j < Num)//已经到达的进程{j++;if (j >= Num){allin = 1;}}}else{j = Num;}j = j - 1;//j是已经到达的进程数while (k <= j)//从已经到达的进程里找到服务时间最短的进程{if (ServiceTime_SJF[k] == 0)//进程的服务时间如果等于0,则跳过该进程k++;else{if (ServiceTime_SJF[min] > ServiceTime_SJF[k])//比较,找到服务时间最短的进程min = k;k++;}}ServiceTime_SJF[min] = 0;//找完后置零,便于下一次循环时使用NowTime += ServiceTime[min];//累加当前时间FinishTime[min] = NowTime;//完成时间}for (i = 0; i < Num; i++)//计算周转时间,带权周转时间,总的周转时间和总的带权周转时间{WholeTime[i] = FinishTime[i] - ArrivalTime[i];WeightWholeTime[i] = (double)WholeTime[i] / ServiceTime[i];SumWT += WholeTime[i];SumWWT += WeightWholeTime[i];}AverageWT_SJF = SumWT / Num;//平均周转时间AverageWWT_SJF = SumWWT / Num;//平均带权周转时间Console.WriteLine("完成时间:{0} 周转时间:{1} 带权周转时间:{2}",FinishTime[0],WholeTime[0],WeightWholeTime[0]);for (i = 1; i < Num; i++)//输出结果{Console.Write("时刻:{0} ", FinishTime[i] - ServiceTime[i]);Console.Write("进程:{0} ", i + 1);Console.Write("开始运行 ");Console.Write("完成时间:{0} ", FinishTime[i]);Console.Write("周转时间:{0} ", WholeTime[i]);Console.Write("带权周转时间:{0} ", WeightWholeTime[i]);Console.WriteLine();}Console.WriteLine("平均周转时间{0},平均带权周转时间{1}", AverageWT_SJF , AverageWWT_SJF );}void input(){Console.Write(" 请输入进程个数:");Num = Convert .ToInt32 (Console.ReadLine());while (Num > 100 || Num <= 0){Console.Write(" 进程数应在0--100之间,请正确输入!");Num = Convert.ToInt32(Console.ReadLine());}Console .WriteLine ("********************************************"); for (i = 0;i < Num ;i++){Console .Write (" 请输入第{0}个进程到达时间:",i+1);ArrivalTime [i] = Convert.ToInt32 (Console .ReadLine ());}Console .WriteLine ("********************************************"); for (i = 0;i < Num ;i++){int data = 0;Console .Write (" 请输入第{0}个进程服务时间:",i+1);data = Convert.ToInt32 (Console .ReadLine ());ServiceTime [i] = data ;ServiceTime_SJF [i] = data ;}Console.WriteLine("********************************************"); Console .Write ("请选择要使用的算法(1-FCFS,2-SJF):");choice = Convert.ToInt32 (Console .ReadLine ());}static void Main(string[] args){char flag = 'y';Program p = new Program();Loop:p.NowTime = 0;p.SumWT = 0;p.SumWWT = 0;//参数初始化p.input();//输入if (p.choice == 1)p.FCFS();//调用FCFS算法else if (p.choice == 2)p.SJF();//调用SJF算法else//输入有误,则重新选择{while (true ){Console.WriteLine("您的选择有误!请重新选择!");Console.Write("请选择要使用的算法(1-FCFS,2-SJF):");p.choice = Convert.ToInt32(Console.ReadLine());if (p.choice == 1){p.FCFS();break;}else if (p.choice == 2){p.SJF();break;}}}Console.WriteLine("是否继续使用该程序,按'y'或'Y'键继续,按其他任意键退出:"); flag = Convert .ToChar (Console .ReadLine ());if (flag == 'y' || flag == 'Y') goto Loop;Console.ReadKey();}}}4.实验结果FCFS:SJF:正常运行如上,其他情况:5.实验过程中出现的问题及解决办法在实现短作业方法过程中,由于没有事先判断其他进程是否需到达队列,直接执行短作业查找出现了问题,改善了程序,首先执行了服务到达的判断,在执行短作业查找,使得问题得到解决。