《操作系统》实验报告——进程调度的模拟

实验内容

熟悉进程调度的各种算法,并对模拟程序给出数据和流程的详细分析,之后画出流程图,最后参考模拟程序写出时间片轮转调度算法的程序

实验目的

通过本实验,加深对进程调度算法原理和过程的理解。

实验要求

(1) 对调度算法进行详细分析,在仔细分析的基础上,完全理解主要数据结构和过程的作用,给出主要数据结构的说明及画出主要模块的流程图。

(2) 根据提示信息,把函数写完整,使成为一个可运行程序。

 

(3) 反复运行程序,观察程序执行的结果,验证分析的正确性,然后给出一次执行的最后运行结果,并由结果计算出周转时间和带权周转时间。

说明:进程生命周期数据。即CPU-I/O时间序列,它是进程运行过程中进行调度、进入不同队列的依据。

如序列:10秒(CPU),500秒(I/O),20秒(CPU),100秒(I/O),30秒(CPU),90秒(I/O),110秒(CPU),60秒(I/O)……,此序列在进程创建时要求自动生成。

源代码

#include  
#include 
#include
#include 
#include 
#include 
#include 
#include 
using namespace std;
struct ProcStruct  
{int  p_pid;         // 进程的标识号char p_state;       // 进程的状态,C--运行  R--就绪  W--组塞  B--后备  F--完成int  p_rserial[10]; // 模拟的进程执行的CPU和I/O时间数据序列,间隔存储,第0项存储随后序列的长度(项数),以便知晓啥时该进程执行结束int  p_pos;   // 当前进程运行到的位置,用来记忆执行到序列中的哪项int  p_starttime;   // 进程建立时间int  p_endtime;     // 进程运行结束时间int  p_cputime;     // 当前运行时间段进程剩余的需要运行时间int  p_iotime;      // 当前I/O时间段进程剩余的I/O时间int  p_next;        // 进程控制块的链接指针
} proc[10];
int   RunPoint;   // 运行进程指针,-1时为没有运行进程
int   WaitPoint;  // 阻塞队列指针,-1时为没有阻塞进程
int   ReadyPoint; // 就绪队列指针,-1时为没有就绪进程
long  ClockNumber;   // 系统时钟
int   ProcNumber;    // 系统中模拟产生的进程总数
int   FinishedProc;    // 系统中目前已执行完毕的进程总数//            显示进程数据序列void DisData()
{ofstream  outFile;     //同时将该信息写入磁盘的某txt文件中 ,该函数要#include outFile.open("1_Process_Info.txt") ;  //该txt 文件名可自己命名,第1次open时磁盘 中没有该文件,系统会创建一个空白的。for(int i=0; i>proc[i].p_pid;for(j=0;j<5;j++) inFile.get(ch);//继续读,扔掉5个字符inFile>>proc[i].p_rserial[0];for(j=0;j<7;j++) inFile.get(ch);//继续读,扔掉7个字符inFile>>proc[i].p_starttime;for(j=0;j<2;j++) inFile.get(ch);//继续读,扔掉2个字符for(k=1;k<=proc[i].p_rserial[0];k++){inFile>>tmp;  proc[i].p_rserial[k]=tmp;}		proc[i].p_state='B';proc[i].p_pos=1;proc[i].p_endtime=0; proc[i].p_next=-1; proc[i].p_cputime=proc[i].p_rserial[1];  proc[i].p_iotime=proc[i].p_rserial[2];     i++; //本行结束,一个进程信息读完,序号+1, 准备 next process }ProcNumber=i-1;  //给ProcNumber赋值,i最后有++,回位下inFile.close();//完工后,记得归位,关灯。
}//            检查是否有新进程到达,有则放入就绪队列void NewReadyProc(void)
{ 	int n;for(int i=0; i 0) return; // 还需要CPU时间,下次继续,这次就返回了//如果不满足以上>0的条件,就意味着=0,就不会自动返回,接着做以下事情。	
// 进程完成本次CPU后的处理if (proc[RunPoint].p_rserial[0]==proc[RunPoint].p_pos) //进程全部序列执行完成{  FinishedProc++;proc[RunPoint].p_state ='F';proc[RunPoint].p_endtime = ClockNumber;	RunPoint=-1;  //无进程执行  NextRunProcess(); //找分派程序去,接着做下一个}	else //进行IO操作,进入阻塞队列{proc[RunPoint].p_pos++;proc[RunPoint].p_state ='W';proc[RunPoint].p_iotime =proc[RunPoint].p_rserial[proc[RunPoint].p_pos];proc[n].p_next == -1; //标记下,就自己一个进程,没带尾巴一起来;否则,当p_next不为-1时,后面的那一串都是被阻塞者n=WaitPoint;if(n == -1) //是阻塞队列第一个I/O进程WaitPoint=RunPoint; else{	do //放入阻塞队列第尾{if(proc[n].p_next == -1) { proc[n].p_next = RunPoint;				  break;}n=proc[n].p_next;} while(n!=-1) ;}RunPoint=-1;   NextRunProcess(); }return;
}//                    显示系统当前状态void  Display_ProcInfo( )
{      int n;system("cls") ;printf("\n       当前系统模拟%2d个进程的运行时钟:%ld\n\n", ProcNumber,ClockNumber);printf("       就绪指针=%d, 运行指针=%d, 阻塞指针=%d\n\n",ReadyPoint,RunPoint,WaitPoint);if(RunPoint!= -1){//Print 当前运行的进程的信息;printf(" .............Running Process .............\n ");printf("当前运行的进程  No.%d ID:%d(%2d,%2d)", RunPoint,proc[RunPoint].p_pid,proc[RunPoint].p_rserial[0],proc[RunPoint].p_starttime);printf(" 总CPU时间=%d, 剩余CPU时间=%d\n",proc[RunPoint].p_rserial[proc[RunPoint].p_pos],proc[RunPoint].p_cputime);}elseprintf("No Process Running !\n");n=ReadyPoint;printf("\n Ready Process ...... \n");while(n!=-1) // 显示就绪进程信息{printf("    [No.%2d ID:%4d],%d,%d,%d\n",n,proc[n].p_pid,proc[n].p_starttime,proc[n].p_rserial[proc[n].p_pos],proc[n].p_cputime );n=proc[n].p_next;}n=WaitPoint;printf("\n Waiting Process ...... \n");while(n!=-1) // 显示阻塞进程信息{  printf("    [No.%2d ID:%4d],%d,%d,%d\n",n,proc[n].p_pid,proc[n].p_starttime,proc[n].p_rserial[proc[n].p_pos],proc[n].p_iotime);n=proc[n].p_next;  }printf("\n=================== 后备进程 ====================\n");for(int i=0; i 0) return; // 还没有完成本次I/O// 进程的I/O完成处理if (proc[WaitPoint].p_rserial[0]==proc[WaitPoint].p_pos) //进程全部任务执行完成{  FinishedProc++;proc[WaitPoint].p_endtime = ClockNumber;proc[WaitPoint].p_state ='F';if(proc[WaitPoint].p_next==-1){ WaitPoint=-1;return ;}else //调度下一个进程进行I/O操作{n=proc[WaitPoint].p_next;proc[WaitPoint].p_next=-1;WaitPoint=n;proc[WaitPoint].p_iotime =proc[WaitPoint].p_rserial[proc[WaitPoint].p_pos] ;return ;}}else //进行下次CPU操作,进就绪队列{bk=WaitPoint;WaitPoint=proc[WaitPoint].p_next;proc[bk].p_pos++;proc[bk].p_state ='R'; //进程状态为就绪proc[bk].p_next =-1;n=ReadyPoint;   if(n == -1) //是就绪队列的第一个进程{  ReadyPoint=bk; return; } else{  do {if(proc[n].p_next == -1) { proc[n].p_next = bk;  break ; }n=proc[n].p_next;}while(n!=-1); }}return ;
}//            显示模拟执行的结果void DisResult(){int i;  printf("\n---------------------------------\n");printf("标识号-时间序列-建立时间-结束时间-周转时间-带权周转时间\n");for(i=0; i %d\t",proc[i].p_pid ,proc[i].p_rserial[0] );printf("%d\t%d\t",proc[i].p_starttime,proc[i].p_endtime);printf("%d\t",proc[i].p_endtime-proc[i].p_starttime);int sumtime=0;for(int j=1; j<=proc[i].p_rserial[0];j++)sumtime+=proc[i].p_rserial[j];printf("%.2f",(proc[i].p_endtime-proc[i].p_starttime)*1.0/sumtime);printf("\n" );}  
}//                     调度模拟算法void Scheduler_FF(void)  //调度模拟算法
{if(ProcNumber==0) //该值居然是0? 只能说用户没创建进程{ Read_Process_Info();//那么,从磁盘读取上次创建的进程信息,赋值给相应变量 		}ClockNumber=0;// 时钟开始计时, 开始调度模拟while(FinishedProc < ProcNumber){ // 执行算法ClockNumber++;  // 时钟前进1个单位NewReadyProc(); // 判别新进程是否到达Cpu_Sched();    // CPU调度IO_Sched();     // IO调度      Display_ProcInfo(); //显示当前状态Sleep(700); }DisResult(); _getch();   
}
/////                      主函数///
int main( )
{char ch;  RunPoint=-1;   // 运行进程指针,-1时为没有运行进程WaitPoint=-1;  // 阻塞队列指针,-1时为没有阻塞进程ReadyPoint=-1; // 就绪队列指针,-1时为没有就绪进程ClockNumber=0;   // 系统时钟ProcNumber=0;    // 当前系统中的进程总数system("cls") ;while ( true )                           {printf("***********************************\n");printf("     1: 建立进程调度数据序列 \n") ;printf("     2: 读进程信息,执行调度算法\n") ;  printf("     3: 显示调度结果 \n") ;printf("     4: 退出\n") ;printf("***********************************\n");printf( "Enter your choice (1 ~ 4): ");  do   ch = (char)_getch() ; //如果输入信息不正确,继续输入while(ch != '1' && ch != '2' && ch != '3'&& ch != '4');if(ch == '4') { printf( "\n");return 0; }   // 选择4,退出   else if(ch == '3') DisResult();       // 选择3    	else if(ch == '2')  Scheduler_FF();     // 选择2        else if(ch == '1') Create_ProcInfo();  // 选择1        _getch() ; system("cls") ;}//结束printf("\nPress Any Key To Continue:");_getch() ;return 0;
}

运行结果

 

参考文章

操作系统实验——进程调度的模拟

实验4 进程调度的模拟

2011 操作系统 实验4 进程调度的模拟(答案Part1)

2011 操作系统 实验4 进程调度的模拟(答案Part2)

2011 操作系统 实验4 进程调度的模拟(源程序)


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部