作業系統 單處理器程序排程模擬實驗(c++)
阿新 • • 發佈:2019-01-29
本實驗模擬了時間片輪轉排程演算法下的單處理機程序排程。
資料結構以程序控制塊PCB為基本單位。
邏輯結構簡單描述為,存在一個準備就緒的佇列,用來組織PCB。
程式開始,需要輸入執行時間片長度,再錄入程式。程式需要數字編號和執行長度。
位於佇列頭的PCB出隊,變為執行態,執行(與模擬的系統暫存器空間互動),執行完畢後,改為就緒態,再次加入隊尾。
</pre><pre name="code" class="cpp">#include<stdio.h> #include<malloc.h> #include<stdlib.h> #include<Windows.h> #include<conio.h> //程序控制塊資料型別 typedef struct pcb { int id; //程序號 int count; //程序工作量 char status; //程序狀態(R和W和F) int ax, bx, cx,dx; //程序現場資訊,通用暫存器內容 int pc; //程序現場資訊,程式計數器內容 int psw; //程序現場資訊,程式狀態字暫存器內容 struct pcb *next; //下一個程序控制塊的位置 } PCB,*QueuePtr; //就緒佇列的指標 typedef struct { QueuePtr front; QueuePtr rear; } ReadyQueue; //系統暫存器資料型別 typedef struct { int ID; int COUNT; char STATUES; int AX,BX,CX,DX,PC,PSW; } OsRegister; //公用變數 ReadyQueue *q; QueuePtr pcb; OsRegister osRegister; int time; //就緒佇列操作方法 //判斷佇列是否為空 int IsEmpty(ReadyQueue *q){ if(q->front==q->rear) return 1; else return 0; } //初始化就緒佇列 ReadyQueue *InitQueue(){ ReadyQueue *q = (ReadyQueue *)malloc(sizeof(ReadyQueue)); if(q!=NULL){ q->front = q->rear = (QueuePtr)malloc(sizeof(PCB)); q->front->next = NULL; } else exit(1); return q; } //將新元素插入隊尾 void EnQueue(ReadyQueue *q,QueuePtr pcb){ if(&pcb!= NULL){ q->rear->next = pcb; q->rear = pcb; }else printf("\n異常!"); } //將隊頭元素出隊 QueuePtr DeQueue(ReadyQueue *q){ if(q->front==q->rear){ printf("\n全部執行完畢佇列為空!"); system("pause"); exit(0); } QueuePtr pcb; pcb = q->front->next; q->front->next = pcb->next; if(q->rear==pcb) q->rear = q->front; return pcb; } //清空佇列 void ClearQueue(ReadyQueue *q){ while(IsEmpty(q)!=1) DeQueue(q); } //銷燬就緒佇列 void DestroyQueue(ReadyQueue *q){ if(IsEmpty(q)!=1) ClearQueue(q); free(q); printf("\n系統已銷燬!"); } //建立PCB QueuePtr Create(int id,int count){ //申請新PCB QueuePtr pcb = (QueuePtr)malloc(sizeof(PCB)); //初始化PCB pcb->id = id; pcb->count = count; pcb->ax = 0; pcb->bx = 0; pcb->cx = 0; pcb->dx = 0; pcb->pc = 0; pcb->psw = 0; pcb->status = 'W'; //返回PCB的指標 return pcb; } //程序排程函式 void schedule(){ while(1){ //出佇列 pcb = DeQueue(q); //加入系統處理器中,改為執行態 osRegister.STATUES = pcb->status = 'R'; osRegister.ID = pcb->id; osRegister.COUNT = pcb->count; //用自增來模擬執行過程,並伴隨暫存器的改變 osRegister.AX = ++pcb->ax; osRegister.BX = ++pcb->bx; osRegister.CX = ++pcb->cx; osRegister.DX = ++pcb->dx; osRegister.PC = ++pcb->pc; osRegister.PSW = ++pcb->psw; printf("\n\n\n"); printf("當前執行的程式為:\n"); printf(" 程序號: %d\n",osRegister.ID); printf(" 程序工作量: %d\n",osRegister.COUNT); printf(" 程序狀態: ");putchar(osRegister.STATUES); printf("\n\n"); printf(" 暫存器資訊\nAX\tBX\tCX\tDX\tPC\tPSW\n"); printf("%d\t%d\t%d\t%d\t%d\t%d\n",osRegister.AX,osRegister.BX,osRegister.CX,osRegister.DX,osRegister.PC,osRegister.PSW); if(osRegister.PSW == osRegister.COUNT){ osRegister.STATUES = pcb->status = 'F'; printf("--------該程序執行完畢!-------- "); continue; } //用一段時間的休眠來模擬時間片下的計算 Sleep(time*1000); pcb->status = 'W'; //將執行完時間片的程序加入佇列尾 EnQueue(q,pcb); } } //主函式 void main(){ //輸入控制 int Id; int Count; q = InitQueue(); printf("程序排程程式開始執行! ^-^\n\n"); printf("請輸入時間片長度(秒):\n"); scanf("%d",&time); printf("(注意:請輸入程序號(非負整數)和該程序的工作量(整數),輸入完最後一個程序後,回車並輸入兩個負整數結束:)\n\n"); for(int i=1;i<11;i++) { fflush(stdin); printf("請輸入第%d個程序的 程序號和工作量:\n",i); scanf("%d%d",&Id,&Count); if(Id<0) break; pcb = (QueuePtr)Create(Id,Count); EnQueue(q,pcb); } schedule(); system("pause"); }