实验内容

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

实验目的

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

实验要求

(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 <windows.h>
#include<iostream>
#include<fstream>
#include <conio.h>
#include <stdlib.h>
#include <io.h>
#include <string.h>
#include <stdio.h>
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 <fstream.h>outFile.open("1_Process_Info.txt") ;  //该txt 文件名可自己命名,第1次open时磁盘 中没有该文件,系统会创建一个空白的。for(int i=0; i<ProcNumber; i++) { //写到txt文件中outFile<< "ID=" << proc[i].p_pid <<"(len="<<proc[i].p_rserial[0]<<",start="<<proc[i].p_starttime<<"):";for(int j=1; j<=proc[i].p_rserial[0];j++)outFile<<" "<<proc[i].p_rserial[j];outFile<<"\n"; //打印到屏幕上   cout<< "ID=" << proc[i].p_pid <<"(len="<<proc[i].p_rserial[0]<<",start="<<proc[i].p_starttime<<"):";for(int j=1; j<=proc[i].p_rserial[0];j++)cout<<" "<<proc[i].p_rserial[j];cout<<"\n";    }outFile.close(); // 写入txt文件的流被冲刷,保存到磁盘上
}//                                                                        //
//  随机生成进程数量和每个CPU--I/O时间数据序列,进程数量控制在5到10之间, //
//  数据序列控制在6到12之间,CPU和I/O的时间数据值在5到15的范围            //
//                                                                        //void Create_ProcInfo(void ) {int s,i,j;srand(GetTickCount());                     // 初始化随机数队列的"种子"ProcNumber=((float) rand() / 32767) * 5 + 5;  // 随机产生进程数量5~10FinishedProc=0;for(i=0;i<ProcNumber;i++)   // 生成进程的CPU--I/O时间数据序列{  proc[i].p_pid=((float) rand() / 32767) * 1000;proc[i].p_state='B';   // 初始都为后备状态s=((float) rand() / 32767) *6 + 6; // 产生的进程数据序列长度在6~12间proc[i].p_rserial[0]=s; // 第一项用于记录序列的长度for(j=1;j<=s;j++)  // 生成时间数据序列,数值在10~30间proc[i].p_rserial[j]=((float) rand() / 32767) *10 + 5;// 赋其他字段的值proc[i].p_pos=1;proc[i].p_starttime=((float) rand() / 32767) *49+1;proc[i].p_endtime=0;   proc[i].p_cputime=proc[i].p_rserial[1];  proc[i].p_iotime=proc[i].p_rserial[2];  proc[i].p_next=-1; }printf("\n---------------------------\n    建立了%d个进程数据序列\n\n", ProcNumber);DisData();printf("\nPress Any Key To Continue.......");_getch() ; return ;
}//   从磁盘读取最后一次生成的进程信息的文件,执行调度,以重现调度情况。void Read_Process_Info()
{ifstream inFile;     // 定义打开文件的文件流char ch; int i,j,k,tmp;      inFile.open("Process_Info.txt") ; // 打开上次写的txt进行信息文件流i=0;while(inFile){ inFile.get(ch);for(j=0;j<3;j++) inFile.get(ch);//扔掉3个字符,        inFile>>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<ProcNumber; i++) {   if (proc[i].p_starttime == ClockNumber) // 进程进入时间达到系统时间,ClockNumber是当前的系统时间{   proc[i].p_state='R';  // 进程状态修改为就绪         proc[i].p_next=-1; // 该进行即将要挂在队列末尾,它肯定是尾巴,后面没人的,所以先设置next=-1if (ReadyPoint==-1) // 如果当前就绪队列无进程ReadyPoint=i;else      // 如果就绪队列有进程,放入队列尾{  n=ReadyPoint;           while(proc[n].p_next!=-1)   n=proc[n].p_next;  //找到原来队伍中的尾巴proc[n].p_next=i;   //挂在这个尾巴后面}}}
}//            选择下一个可以运行的进程void NextRunProcess(){if (ReadyPoint==-1) { RunPoint = -1; return;}  // 就绪队列也没有等待的进程proc[ReadyPoint].p_state ='C';   RunPoint=ReadyPoint;   proc[ReadyPoint].p_cputime =proc[ReadyPoint].p_rserial[proc[ReadyPoint].p_pos] ;   ReadyPoint=proc[ReadyPoint].p_next;proc[RunPoint].p_next = -1;
}//            CPU调度void Cpu_Sched(void)
{ int n;if (RunPoint == -1)    // 没有进程在CPU上执行{        NextRunProcess();   return;     }proc[RunPoint].p_cputime--;      // 进程CPU执行时间减少1个时钟单位if (proc[RunPoint].p_cputime > 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<ProcNumber; i++) if (proc[i].p_state=='B')printf("    [No.%2d ID:%4d],%d\n",i,proc[i].p_pid,proc[i].p_starttime); printf("\n================ 已经完成的进程 =================\n");for(int i=0; i<ProcNumber; i++) if (proc[i].p_state=='F')printf("    [No.%2d ID:%4d],%d,%d\n",i,proc[i].p_pid,proc[i].p_starttime,proc[i].p_endtime);}//            I/O调度void  IO_Sched(){int n,bk;if (WaitPoint==-1) return;   // 没有等待I/O的进程,直接返回proc[WaitPoint].p_iotime--;  // 进行1个时钟的I/O时间 if (proc[WaitPoint].p_iotime > 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<ProcNumber; i++) {  printf("ID=%d -> %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 进程调度的模拟(源程序)

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

  1. 操作系统实验(进程调度)

    操作系统实验(进程调度) 一.实验目的 二.实验内容 三.实验准备 3.1优先权算法 3.2时间片轮转调度算法 四.实验 一.实验目的   1.1理解有关进程控制块.进程队列的概念.   1.2掌握进 ...

  2. 操作系统实验报告18:硬盘柱面访问调度算法

    操作系统实验报告18 实验内容 实验内容:硬盘调度. 编写 C 程序模拟实现课件 Lecture25 中的硬盘柱面访问调度算法 包括 FCFS.SSTF.SCAN.C-SCAN.LOOK.C-LOOK ...

  3. 操作系统实验报告17:请求页面置换算法

    操作系统实验报告17 实验内容 实验内容:虚拟存储管理. 编写一个 C 程序模拟实现课件 Lecture24 中的请求页面置换算法 包括FIFO.LRU (stack and matrix imple ...

  4. 操作系统实验报告16:CPU 调度

    操作系统实验报告16 实验内容 实验内容:CPU 调度. 讨论课件 Lecture19-20 中 CPU 调度算法的例子,尝试基于 POSIX API 设计一个简单调度器(不考虑资源竞争问题): 创建 ...

  5. 操作系统实验报告1:ucore Lab 1

    操作系统实验报告1 实验内容 阅读 uCore 实验项目开始文档 (uCore Lab 0),准备实验平台,熟悉实验工具. uCore Lab 1:系统软件启动过程 (1) 编译运行 uCore La ...

  6. 计算机操作系统实验之进程调度(一)轮转调度法(C语言)

    计算机操作系统实验之进程调度(一)轮转调度法(C语言) 实验目的 实验内容与基本要求 轮转调度法的基本原理 实现思路及功能分析 算法流程图 全部代码 工程图 ProcessScheduling.h P ...

  7. linux系统编程界面实验报告,操作系统实验报告-Linux操作使用编程.doc

    操作系统实验报告-Linux操作使用编程 实 验 报 告( 2012/ 2013 学年 第二学期) 课程名称操 作 系 统A实验名称Linux操作.使用.编程实验时间2013年 5 月 6日指导单位计 ...

  8. 操作系统实验报告【太原理工大学】

    操作系统实验报告 温馨提示:仅供参考! 目录 操作系统实验报告 一.进程调度程序设计 1.程序清单 2.运行结果 3.分析总结 二.页式虚拟存储管理程序设计 1.程序清单 2.运行结果 3.分析总结 ...

  9. 实验报告Linux操作系统基本命令,linux操作系统实验报告全部.doc

    linux操作系统实验报告全部 计算机操作系统 实验报告 学 号:姓 名:提交日期:2014.12.15成 绩: 东北大学秦皇岛分校 [实验题目]熟悉Linux/UNIX操作系统[实验目的]1.熟悉L ...

最新文章

  1. 如果文件夹不存在,请创建它
  2. PCA目标函数的推导
  3. MacOS安装react。问题 -- npm全局包的权限问题
  4. 给网游写一个挂吧(四) – 调用游戏函数
  5. dateformat 返回类型_SpringBoot返回date日期格式化
  6. yy自动语音接待机器人_人脸签到、发言记录,会议机器人来啦
  7. android 跟随动画,Android实现View拖拽跟随手指移动效果
  8. linux mysql怎么建数据库用户,Linux MySQL新建用户
  9. Flink算子(Filter、KeyBy、Reduce和Aggregate)
  10. java判断浏览器类型_判断浏览器类型
  11. 智能优化算法(源码)-樽海鞘优化算法(Salp Swarm Algorithm,SSA)
  12. logitech鼠标接收器配对
  13. C rgb565转rgb888
  14. TCA9548A IIC多路扩展模块使用
  15. R语言实现非线性回归
  16. kent beck_肯特·沙基(Kent Sharkey)身着“ heezy fo'sheezy babay”!
  17. Soul向港交所递交上市申请,持续发力社交元宇宙赛道
  18. 07-HTML5举例:简单的视频播放器
  19. 如何快速把多个excel表合并成一个excel表(不熟悉vba及公式的人)
  20. IOS7越狱后无法开机,白苹果恢复固件

热门文章

  1. 北大poj1018题解题报告
  2. 让IE6支持图片半透明
  3. 在SQLSERVER EXPRESS 2005中安装northwind和pubs数据库。
  4. php 访问网页返回值,Ping网站并用PHP返回结果
  5. android7.1开机监听广播,Android7.1 Audio Debug相关方法
  6. mac怎么实现文件读写c语言,使用Sublime Text和Xcode在Mac上进行文件输入/输出。 C语言...
  7. [设计模式笔记]4.建造者模式
  8. 计算机网络电缆被拔出是怎么办,网络电缆被拔出是什么意思?网络电缆被拔出的修复办法...
  9. mysql 结构优化建议_MySQL优化之表结构优化的5大建议(数据类型选择讲的很好)...
  10. java模拟浏览器不关闭会话_JSP实现浏览器关闭cookies情况下的会话管理