操作系统 单处理器进程调度模拟实验(c++)

来源:互联网 发布:php为什么比aps.net好 编辑:程序博客网 时间:2024/05/17 22:08

本实验模拟了时间片轮转调度算法下的单处理机进程调度。

数据结构以进程控制块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;elsereturn 0;}//初始化就绪队列ReadyQueue *InitQueue(){ReadyQueue *q = (ReadyQueue *)malloc(sizeof(ReadyQueue));if(q!=NULL){q->front = q->rear = (QueuePtr)malloc(sizeof(PCB));q->front->next = NULL;}elseexit(1);return q;}//将新元素插入队尾void EnQueue(ReadyQueue *q,QueuePtr pcb){if(&pcb!= NULL){q->rear->next = pcb;q->rear = pcb;}elseprintf("\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系统已销毁!");}//创建PCBQueuePtr Create(int id,int count){//申请新PCBQueuePtr pcb = (QueuePtr)malloc(sizeof(PCB));//初始化PCBpcb->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");}



0 0
原创粉丝点击