www.pudn.com > 200652619472986557.rar > Schedule.cpp
// Schedule.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include "Schedule.h" #include#include #include #include #include
#include #include #include #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // The one and only application object using namespace std; //颜色 #define CLR_GREEN 10 //绿 #define CLR_RED 12 //红 #define CLR_SECRED 13 //次红 #define CLR_YELLOW 14 //黄 #define CLR_IN CLR_RED //输入颜色 #define CLR_NORMALOUT CLR_GREEN //一般输出颜色 #define CLR_CRITICALOUT CLR_RED //重要输出颜色 #define CLR_NORMALRESULT CLR_YELLOW //一般结果输出颜色 #define CLR_CRITICALRESULT CLR_RED //重要结果输出 #define CLR_SECCRITICALRESULT CLR_SECRED //次重要结果输出 //声音类型 #define CB_ERROR 0 //错误 #define CB_OK 1 //正确 #define RANDDF rand()*1.0/RAND_MAX //产生0~1之间的随机小数 struct PCB; struct PCBPriorityCompare; struct PCBProgLenCompare; struct STATINFO_PROGLEN; struct STATINFO_PRIORITY; typedef int INSTRUCTION; //指令 typedef queue PCBQUEUE; //进程控制块队列 typedef list PCBPQUEUE; //进程控制块优先级队列 typedef vector INSTRUCTIONSET; //指令集合 typedef list STATINFOL_PROGLEN; //统计信息链表:程序长度 typedef list STATINFOL_PRIORITY; //统计信息链表:进程优先级 //进程状态 enum PROCSTATUS { Ready, //就绪 Block, //阻塞 Run, //运行 }; //进程优先级 enum PROCPRIORITY { Low, //低 LowStandard, //低于标准 Standard, //标准 HighStandard, //高于标准 High, //高 RealTime, //实时 }; //调度算法 enum SCHEDULEALGORITHM { FCFS, //先来先服务 SPF, //短进程优先 FPF_Reaved, //抢占式高优先级 TimePiece, //时间片轮转 }; //进程标识符 struct PROCID { int nInID; //内部标识符 int nOutID; //外部标识符 }; //处理机状态 struct PROCESSORSTATUS { int nIP; //指令指针 }; //进程调度信息 struct PROCSCHINFO { PROCSTATUS statusProc; //进程状态 PROCPRIORITY procPriority; //进程优先级 }; //进程控制信息 struct PROCCONINFO { PCB *pNextPCB; //下一PCB }; //程序 struct PROGRAM { int nProgLen; //程序大小 int nIP; //指令指针 SYSTEMTIME timeSystem; //程序请求运行时间 INSTRUCTIONSET instructionSet; //指令集合 }; //统计信息 struct STATINFO { int nRequestTime; //进程请求运行时间 int nGetCPUTime; //系统为之提供服务时间 }; //进程控制块 struct PCB { STATINFO infoStat; //统计信息 PROCID idProc; //进程标识符 PROGRAM program; //该进程对应的程序 PROCESSORSTATUS statusProcessor; //处理机状态 PROCSCHINFO infoProcSch; //进程调度信息 PROCCONINFO infoProcCon; //进程控制信息 }; //统计信息:程序长度 struct STATINFO_PROGLEN { int nProgLen; //程序长度 int nProcID; //进程ID int nPeriod; //周转时间 int nWeightPeriod; //带权周转时间 bool operator < (STATINFO_PROGLEN infoStat) { return nProgLen < infoStat.nProgLen; } }; //统计信息:进程优先级 struct STATINFO_PRIORITY { PROCPRIORITY procPriority; //进程优先级 int nProcID; //进程ID int nPeriod; //周转时间 int nWeightPeriod; //带权周转时间 bool operator < (STATINFO_PRIORITY infoStat) { return procPriority < infoStat.procPriority; } }; DWORD WINAPI GetRandProc(LPVOID lpParam); //产生随机随机进程并插入就绪队列 void Schedule_FCFS(); //FCFS调度 void Schedule_SPF(); //短作业优先 void Schedule_FPF_Reaved(); //高优先权调度 void Schedule_TimePiece(); //时间片调度 void Schedule(); //调度程序 BOOL RunProc(PCB *pPcb); //运行进程 void AboutMe(); //关于 void Exit(); //退出系统 void PressAnyKey(); //按任意键继续 void CoolBeep(UINT uiCbSort); //非常酷的蜂鸣声 void AnimatePrint(char* pStr); //动态显示 void Reset(SCHEDULEALGORITHM algo); //重新设置初值 void PrintPriority(PROCPRIORITY p); //以文字方式打印优先级 BOOL CtrlHandler(DWORD dwCtrlType); //处理控制台事件 void Clean(); //事后清理 void PrintAlgorithm(SCHEDULEALGORITHM algo); //打印算法 void PrintStatInfo_ProgLen(STATINFOL_PROGLEN l,SCHEDULEALGORITHM algo); //打印统计信息:程序长度 void PrintStatInfo_Priority(STATINFOL_PRIORITY l,SCHEDULEALGORITHM algo);//打印统计信息:进程优先级 void SortInsProgLenQ(PCBPQUEUE& pcbQ,PCB pcb); //按程序大小入队列 void SortInsPriorityQ(PCBPQUEUE& pcbQ,PCB pcb); //按优先级入队列 int g_nCloseTime; //模拟时间 int g_nMaxRunTime; //程序最大运行时间 int g_nMaxInterval; //最大间隔 int g_nMaxTimePiece; //最大时间片 int g_nCurProcID=0; //当前进程ID PCB g_CurRunningProc; //当前正在运行的进程 int g_nFinishedTime=0; //模拟已完成的时间 BOOL g_bIsEnd=FALSE; //结束标志 BOOL g_bProgIsRun; //是否有程序正在运行 BOOL g_bIsPrioritierReach=FALSE; //是否有优先级更高的进程达到 PCB g_pcbPrioritier; //更高优先级的进程 PCBQUEUE g_pcbReadyQueue; //就绪队列 PCBPQUEUE g_pcbReadyPriorityQueue; //就绪优先级队列 SCHEDULEALGORITHM g_ScheduleAlgorithm; //调度算法 CRITICAL_SECTION g_CriticalSection; //临界区 STATINFOL_PROGLEN g_listStatInfoProgLen[3]; //统计信息链表:程序长度 STATINFOL_PRIORITY g_listStatInfoProcPriority; //统计信息链表:进程优先级 HANDLE g_hStdOut=GetStdHandle(STD_OUTPUT_HANDLE); int _tmain(int argc, TCHAR* argv[], TCHAR* envp[]) { int nRetCode = 0; // initialize MFC and print and error on failure if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0)) { // TODO: change error code to suit your needs cerr << _T("Fatal Error: MFC initialization failed") << endl; nRetCode = 1; } UCHAR ucSelection;//选择号 srand(time(0)); InitializeCriticalSection(&g_CriticalSection); SetConsoleTitle("进程调度算法演示及其性能测试系统");//设置标题 SetConsoleCtrlHandler((PHANDLER_ROUTINE)CtrlHandler,TRUE); Select: SetConsoleTextAttribute(g_hStdOut,CLR_NORMALOUT); cout< '6') { if(ucSelection==27) { cout< dwCursorPosition.X-1; dwCursorPostion.Y=lpConsoleScreenBufferInfo->dwCursorPosition.Y; SetConsoleCursorPosition(g_hStdOut,dwCursorPostion); FillConsoleOutputCharacter(g_hStdOut,' ',1,dwCursorPostion,0); goto Input; } cout< g_pcbReadyPriorityQueue.front().infoProcSch.procPriority) { g_bIsPrioritierReach=TRUE; g_pcbPrioritier=pcb; } } SortInsPriorityQ(g_pcbReadyPriorityQueue,pcb); LeaveCriticalSection(&g_CriticalSection); break; case TimePiece: g_pcbReadyPriorityQueue.push_back(pcb); break; } uDelay=RANDDF*(g_nMaxInterval-1)+1; if((g_nFinishedTime+=uDelay)<=g_nCloseTime) { g_nCurProcID++; Sleep(uDelay); goto ContinueGet; } else g_bIsEnd=TRUE; return 0; } //调度程序 void Schedule() { switch(g_ScheduleAlgorithm) { case FCFS: Schedule_FCFS(); break; case SPF: Schedule_SPF(); break; case FPF_Reaved: Schedule_FPF_Reaved(); break; case TimePiece: Schedule_TimePiece(); break; } } //FCFS调度 void Schedule_FCFS() { PCB pcb; PROGRAM program; int nIP=0; Schedule: if(g_bIsEnd && g_pcbReadyQueue.empty()) { g_listStatInfoProgLen[FCFS].sort(); PrintStatInfo_ProgLen(g_listStatInfoProgLen[FCFS],FCFS); return; } if(g_pcbReadyQueue.empty()) goto Schedule; EnterCriticalSection(&g_CriticalSection); pcb=g_pcbReadyQueue.front(); g_pcbReadyQueue.pop(); LeaveCriticalSection(&g_CriticalSection); RunProc(&pcb); //添加统计信息 STATINFO_PROGLEN infoStat; infoStat.nPeriod=GetTickCount()-pcb.infoStat.nRequestTime; infoStat.nProgLen=pcb.program.nProgLen; infoStat.nProcID=pcb.idProc.nInID; infoStat.nWeightPeriod=infoStat.nPeriod/pcb.infoStat.nGetCPUTime; g_listStatInfoProgLen[FCFS].push_back(infoStat); goto Schedule; } //短进程优先 void Schedule_SPF() { PCB pcb; Schedule: if(g_bIsEnd && g_pcbReadyPriorityQueue.empty()) { g_listStatInfoProgLen[SPF].sort(); PrintStatInfo_ProgLen(g_listStatInfoProgLen[SPF],SPF); return; } if(g_pcbReadyPriorityQueue.empty()) goto Schedule; EnterCriticalSection(&g_CriticalSection); pcb=g_pcbReadyPriorityQueue.front(); g_pcbReadyPriorityQueue.pop_front(); LeaveCriticalSection(&g_CriticalSection); RunProc(&pcb); //添加统计信息 STATINFO_PROGLEN infoStat; infoStat.nPeriod=GetTickCount()-pcb.infoStat.nRequestTime; infoStat.nProgLen=pcb.program.nProgLen; infoStat.nProcID=pcb.idProc.nInID; infoStat.nWeightPeriod=infoStat.nPeriod/pcb.infoStat.nGetCPUTime; g_listStatInfoProgLen[SPF].push_back(infoStat); goto Schedule; } //抢占式高优先权调度 void Schedule_FPF_Reaved() { PCB *pPcb; PCBPQUEUE::iterator p; Schedule: if(g_bIsEnd && g_pcbReadyPriorityQueue.empty()) { g_listStatInfoProgLen[FPF_Reaved].sort(); PrintStatInfo_ProgLen(g_listStatInfoProgLen[FPF_Reaved],FPF_Reaved); return; } if(g_pcbReadyPriorityQueue.empty()) goto Schedule; EnterCriticalSection(&g_CriticalSection); p=g_pcbReadyPriorityQueue.begin(); pPcb=&g_pcbReadyPriorityQueue.front(); g_bProgIsRun=TRUE; LeaveCriticalSection(&g_CriticalSection); if(RunProc(pPcb)) { //添加统计信息 STATINFO_PROGLEN infoStat; infoStat.nPeriod=GetTickCount()-pPcb->infoStat.nRequestTime; infoStat.nProgLen=pPcb->program.nProgLen; infoStat.nProcID=pPcb->idProc.nInID; infoStat.nWeightPeriod=infoStat.nPeriod/pPcb->infoStat.nGetCPUTime; g_listStatInfoProgLen[FPF_Reaved].push_back(infoStat); EnterCriticalSection(&g_CriticalSection); g_pcbReadyPriorityQueue.erase(p); LeaveCriticalSection(&g_CriticalSection); } g_bProgIsRun=FALSE; goto Schedule; } //时间片调度 void Schedule_TimePiece() { PCB pcb; Schedule: if(g_bIsEnd && g_pcbReadyPriorityQueue.empty()) { g_listStatInfoProcPriority.sort(); PrintStatInfo_Priority(g_listStatInfoProcPriority,TimePiece); return; } if(g_pcbReadyPriorityQueue.empty()) goto Schedule; EnterCriticalSection(&g_CriticalSection); pcb=g_pcbReadyPriorityQueue.front(); g_pcbReadyPriorityQueue.pop_front(); LeaveCriticalSection(&g_CriticalSection); if(!RunProc(&pcb)) { EnterCriticalSection(&g_CriticalSection); g_pcbReadyPriorityQueue.push_back(pcb); LeaveCriticalSection(&g_CriticalSection); } else { //添加统计信息 STATINFO_PRIORITY infoStat; infoStat.nPeriod=GetTickCount()-pcb.infoStat.nRequestTime; infoStat.procPriority=pcb.infoProcSch.procPriority; infoStat.nProcID=pcb.idProc.nInID; infoStat.nWeightPeriod=infoStat.nPeriod/pcb.infoStat.nGetCPUTime; g_listStatInfoProcPriority.push_back(infoStat); } goto Schedule; } //运行程序 BOOL RunProc(PCB *pPcb) { int i; PROGRAM *pProgram=&pPcb->program; int nProcID=pPcb->idProc.nInID; int nSize=pProgram->instructionSet.size(); int nTimePieceCnt=0; int nStartTime=GetTickCount(); // cout.unsetf(cout.dec); // cout.setf(cout.hex); switch(g_ScheduleAlgorithm) { case FCFS: EnterCriticalSection(&g_CriticalSection); SetConsoleTextAttribute(g_hStdOut,CLR_CRITICALRESULT); cout< timeSystem.wMinute<<"分" < timeSystem.wSecond<<"秒" < timeSystem.wMilliseconds<<"微秒"< instructionSet[i]); LeaveCriticalSection(&g_CriticalSection); } pPcb->infoStat.nGetCPUTime=GetTickCount()-nStartTime; if(!pPcb->infoStat.nGetCPUTime) pPcb->infoStat.nGetCPUTime+=2; EnterCriticalSection(&g_CriticalSection); SetConsoleTextAttribute(g_hStdOut,CLR_CRITICALRESULT); cout<<"进程"< nProgLen< instructionSet[i]); LeaveCriticalSection(&g_CriticalSection); } pPcb->infoStat.nGetCPUTime=GetTickCount()-nStartTime; if(!pPcb->infoStat.nGetCPUTime) pPcb->infoStat.nGetCPUTime=2; EnterCriticalSection(&g_CriticalSection); SetConsoleTextAttribute(g_hStdOut,CLR_CRITICALRESULT); cout<<"进程"< nIP) { cout< infoProcSch.procPriority); cout< infoProcSch.procPriority); cout< nIP;i infoProcSch.procPriority); SetConsoleTextAttribute(g_hStdOut,CLR_CRITICALRESULT); cout<<")被中断执行"< nIP=i; pPcb->infoStat.nGetCPUTime+=GetTickCount()-nStartTime; return FALSE; } EnterCriticalSection(&g_CriticalSection); SetConsoleTextAttribute(g_hStdOut,CLR_NORMALRESULT); printf("进程%2d正在运行指令%4X...",nProcID,pProgram->instructionSet[i]); cout<<"(优先级为"; SetConsoleTextAttribute(g_hStdOut,CLR_NORMALOUT); PrintPriority(pPcb->infoProcSch.procPriority); cout<<")"< infoStat.nGetCPUTime+=GetTickCount()-nStartTime; if(!pPcb->infoStat.nGetCPUTime) pPcb->infoStat.nGetCPUTime=2; EnterCriticalSection(&g_CriticalSection); SetConsoleTextAttribute(g_hStdOut,CLR_CRITICALRESULT); cout<<"进程"< nIP) { cout< program.nProgLen< program.nProgLen< nIP;i g_nMaxTimePiece) { EnterCriticalSection(&g_CriticalSection); SetConsoleTextAttribute(g_hStdOut,CLR_CRITICALRESULT); cout<<"进程"< nIP=i; pPcb->infoStat.nGetCPUTime+=GetTickCount()-nStartTime; return FALSE; } EnterCriticalSection(&g_CriticalSection); SetConsoleTextAttribute(g_hStdOut,CLR_NORMALRESULT); printf("进程%2d正在运行指令%4X...\n",nProcID,pProgram->instructionSet[i]); LeaveCriticalSection(&g_CriticalSection); nTimePieceCnt++; } pPcb->infoStat.nGetCPUTime+=GetTickCount()-nStartTime; if(!pPcb->infoStat.nGetCPUTime) pPcb->infoStat.nGetCPUTime=2; EnterCriticalSection(&g_CriticalSection); SetConsoleTextAttribute(g_hStdOut,CLR_CRITICALRESULT); cout<<"进程"< (*p).infoProcSch.procPriority) { pcbQ.insert(p,pcb); return; } } pcbQ.push_back(pcb); } //以文字方式打印优先级 void PrintPriority(PROCPRIORITY p) { switch(p) { case Low: cout<<"\"低\""; break; case LowStandard: cout<<"\"低于标准\""; break; case Standard: cout<<"\"标准\""; break; case HighStandard: cout<<"\"高于标准\""; break; case High: cout<<"\"高\""; break; case RealTime: cout<<"\"实时\""; break; } } //打印统计信息:程序长度 void PrintStatInfo_ProgLen(STATINFOL_PROGLEN l,SCHEDULEALGORITHM algo) { int nPeriod=0; int nWeightPeriod=0; int nSize=l.size(); SetConsoleTextAttribute(g_hStdOut,CLR_NORMALRESULT); cout<