《操作系统》实验报告——进程调度的模拟
实验内容
熟悉进程调度的各种算法,并对模拟程序给出数据和流程的详细分析,之后画出流程图,最后参考模拟程序写出时间片轮转调度算法的程序。
实验目的
通过本实验,加深对进程调度算法原理和过程的理解。
实验要求
(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 进程调度的模拟(源程序)
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
