模拟进程调度

举报
兔老大 发表于 2021/04/20 01:18:57 2021/04/20
【摘要】 功能 data.h #ifndef _Data_h_#define _Data_h_ #include <stdio.h>#include <stdlib.h>#include <string.h> #define ElemType PCB#define Status int#define OK 1#define ERROR 0#de...

功能

data.h


      #ifndef _Data_h_
      #define _Data_h_
      #include <stdio.h>
      #include <stdlib.h>
      #include <string.h>
      #define ElemType PCB
      #define Status int
      #define OK 1
      #define ERROR 0
      #define TimeSlice 1
      #define Infinity 10 //INT_MAX
      #define NAME_MAXSIZE 20
      typedef enum
      {
       Ready,Running,Block
      }ProState;
      typedef enum
      {
       FCFS, SPF		//先来先服务,短进程优先
      }PriorityRule;
      typedef struct
      {
      char Name[NAME_MAXSIZE];	//进程名
      int Priority; //优先数
      int ArrivalTime;			//到达时间 以时间片为单位
      int NeedRunningTime;		//运行时间 以时间片为单位
      int StartTime; //开始执行时间
      int FinishTime; //完成时间
      int TimeUsedCPU;			//已用CPU时间 以时间片为单位
       ProState ProcessState;		//进程状态
      }PCB;
      typedef struct Node
      {
       ElemType data;
      struct Node * Next;
      }LNode,*LinkList;
      #endif
  
 

 ChainList.h


      #ifndef _ChainList_h_
      #define _ChainList_h_
      #include "Data.h"
      //功能:链表初始化
      Status Init(LinkList *L);
      //功能:赋值运算,将e2赋值给e1
      void Assignment(ElemType *e1, ElemType e2);
      //功能:获取第i个结点元素
      Status GetElemt_L(LinkList L,int i,ElemType *e);
      //功能:链表根据优先级插入元素
      Status ListInsert_L(LinkList L,ElemType e);
      //功能:链表删除头结点
      Status ListDelete_L(LinkList L,ElemType *e);
      #endif
  
 

ProPCB.h


      #ifndef _ProPCB_h_
      #define _ProPCB_h_
      #include "ChainList.h"
      //功能:将e插入链表Q
      Status GetProcess(LinkList Q,ElemType e);		//上就绪队列
      //功能:根据不同的优先级规则,返回优先数
      int GetPriority(ElemType *e, PriorityRule PR);  //根据不同的规则PR 设置优先数
      //功能:将链表Q的头结点数据放到e指向的内存,并删除
      Status OutProsess(LinkList Q,ElemType *e); //下就绪队列
      //功能:CPU运行pcb指向的进程,并输出所有进行进程状态
      Status CPURunPro(LinkList Q, PCB *pcb); //CPU运行PCB
      //功能:打印所有PCB信息
      void PrintProQueue(LinkList Q, PCB *pcb);		//打印运行后PCB信息
      //功能:当一个进程结束,打印进程信息
      void PrintProResult(PCB *pcb);
      #endif
  
 

实现


      #include "ChainList.h"
      extern int CPUUsedTime;
      //功能:链表初始化
      Status Init(LinkList *L)
      {
       *L = (LinkList)malloc(sizeof(LNode));
       (*L)->data.NeedRunningTime = -1;
       (*L)->Next = NULL;
      return OK;
      }
      //功能:赋值运算,将e2赋值给e1
      void Assignment(ElemType *e1, ElemType e2)
      {
       e1->ArrivalTime = e2.ArrivalTime;
      strcpy(e1->Name,e2.Name);
       e1->Priority = e2.Priority;
       e1->ProcessState = e2.ProcessState;
       e1->FinishTime = e2.FinishTime;
       e1->StartTime = e2.StartTime;
       e1->NeedRunningTime = e2.NeedRunningTime;
       e1->TimeUsedCPU = e2.TimeUsedCPU;
      }
      //链表中按照优先级:从大到小排序插入
      Status ListInsert_L(LinkList L,ElemType e) //这样修改应该不对 p = *L出错
      {
       LinkList p = L->Next, pre = L, s;
      while (p && e.Priority <= p->data.Priority)
       {
       pre = p;
       p = p->Next;
       }
       s = (LinkList)malloc(sizeof(LNode));
       Assignment(&s->data, e);
       s->Next = pre->Next;
       pre->Next = s;
      return OK;
      }
      //链表中头部删除
      Status ListDelete_L(LinkList L,ElemType *e)
      {
       LinkList p = L, q;
       q = p->Next;
      if(!q)
      return ERROR;
       p->Next = q->Next;
       Assignment(e, q->data);
      free(q);
      return OK;
      }
  
 

      #include "ProPCB.h"
      extern int CPUUsedTime;
      //功能:将e插入链表Q
      Status GetProcess(LinkList Q,ElemType e)
      {
      return ListInsert_L(Q, e);
      }
      //功能:根据不同的优先级规则,返回优先数
      int GetPriority(ElemType *e, PriorityRule PR)
      {
      if(PR == FCFS)
      return Infinity - e->ArrivalTime;
      else if(PR == SPF)
      return Infinity - e->NeedRunningTime;
      else
      printf("GetPriority Function ERROR!\n");
      return ERROR;
      }
      //功能:将链表Q的头结点数据放到e指向的内存,并删除
      Status OutProsess(LinkList Q,ElemType *e)
      {
      return ListDelete_L(Q ,e);
      }
      //上一次CPU运行时间增加1个时间片
      Status CPURunPro(LinkList Q,PCB *pcb)
      {
      if(pcb->StartTime == -1)
       pcb->StartTime = CPUUsedTime;
       pcb->ProcessState = Running;
      //PrintProQueue(Q, pcb);
       pcb->TimeUsedCPU += TimeSlice;
      return OK;
      }
      //功能:打印所有PCB信息
      void PrintProQueue(LinkList Q, PCB *pcb)
      {
       LinkList p = Q->Next;
      printf("进程名 优先数 到达时间 运行时间 已用CPU时间 完成时间 进程状态\n");
      if(pcb)
      printf(" %4s %2d %4d %4d %3d(+1) %3d %4s \n",
       pcb->Name,pcb->Priority,pcb->ArrivalTime,pcb->NeedRunningTime,
       pcb->TimeUsedCPU, pcb->FinishTime,pcb->ProcessState == Ready ? "就绪" : "运行");
      while (p)
       {
      printf(" %4s %2d %4d %4d %3d %3d %4s \n",
       p->data.Name,p->data.Priority,p->data.ArrivalTime,p->data.NeedRunningTime,
       p->data.TimeUsedCPU,p->data.FinishTime, p->data.ProcessState == Ready ? "就绪" : "运行");
       p = p->Next;
       }
      printf("-------------------------------------------------------------------------------\n");
      }
      //功能:当一个进程结束,打印进程信息
      void PrintProResult(PCB *pcb)
      {
      printf("进程名 到达时刻 运行时间 开始时刻 完成时刻 周转时间 带权周转时间 进程状态\n");
      if(pcb)
      printf(" %2s %3d %4d %4d %3d %4d %5.2lf %4s \n",
       pcb->Name,pcb->ArrivalTime,pcb->NeedRunningTime,pcb->StartTime,pcb->FinishTime,
       pcb->FinishTime-pcb->ArrivalTime,((pcb->FinishTime - pcb->ArrivalTime)*1.0)/pcb->NeedRunningTime,"完成");
      printf("-------------------------------------------------------------------------------\n");
      }
  
 

main:


      #include "ProPCB.h"
      /****************************
      * 实验01: 非抢占式静态优先权 *
      * ① 优先权始终保持不变 *
      * ② 一旦进入CPU便运行到结束 *
      * ③ FCFS只考虑到达时间进CPU *
      * ④ SPF认为到达时间相同 *
      ****************************/
      int CPUUsedTime = 0;
      void InputData(LinkList * pPCBdata, PriorityRule PR)
      {
       ElemType e = {{0},-1,-1,-1,-1,-1,0,Ready};
       e.ArrivalTime = 0;
       e.ProcessState = Ready;
       e.TimeUsedCPU = 0;
      strcpy(e.Name,"A");
       e.NeedRunningTime = 1;
       e.Priority = GetPriority(&e, PR);
      if(PR == SPF)   e.ArrivalTime = 0;
       GetProcess(*pPCBdata,e);
       e.ArrivalTime = 1;
       e.ProcessState = Ready;
       e.TimeUsedCPU = 0;
      strcpy(e.Name,"B");
       e.NeedRunningTime = 100;
       e.Priority = GetPriority(&e, PR);
      if(PR == SPF)   e.ArrivalTime = 0;
       GetProcess(*pPCBdata,e);
       e.ArrivalTime = 2;
       e.ProcessState = Ready;
       e.TimeUsedCPU = 0;
      strcpy(e.Name,"C");
       e.NeedRunningTime = 1;
       e.Priority = GetPriority(&e, PR);
      if(PR == SPF)   e.ArrivalTime = 0;
       GetProcess(*pPCBdata,e);
       e.ArrivalTime = 3;
       e.ProcessState = Ready;
       e.TimeUsedCPU = 0;
      strcpy(e.Name,"D");
       e.NeedRunningTime = 100;
       e.Priority = GetPriority(&e, PR);
      if(PR == SPF)   e.ArrivalTime = 0;
       GetProcess(*pPCBdata,e);
      }
      //void InputData1(LinkList * pPCBdata, PriorityRule PR)
      //{
      // ElemType e = {{0},-1,-1,-1,-1,-1,0,Ready};
      // e.ArrivalTime = 0;
      // e.ProcessState = Ready;
      // e.TimeUsedCPU = 0;
      // strcpy(e.Name,"A");
      // e.NeedRunningTime = 4;
      // e.Priority = GetPriority(&e, PR);
      // if(PR == SPF) e.ArrivalTime = 0;
      // GetProcess(*pPCBdata,e);
      //
      // e.ArrivalTime = 1;
      // e.ProcessState = Ready;
      // e.TimeUsedCPU = 0;
      // strcpy(e.Name,"B");
      // e.NeedRunningTime = 3;
      // e.Priority = GetPriority(&e, PR);
      // if(PR == SPF) e.ArrivalTime = 0;
      // GetProcess(*pPCBdata,e);
      //
      // e.ArrivalTime = 2;
      // e.ProcessState = Ready;
      // e.TimeUsedCPU = 0;
      // strcpy(e.Name,"C");
      // e.NeedRunningTime = 5;
      // e.Priority = GetPriority(&e, PR);
      // if(PR == SPF) e.ArrivalTime = 0;
      // GetProcess(*pPCBdata,e);
      //
      // e.ArrivalTime = 3;
      // e.ProcessState = Ready;
      // e.TimeUsedCPU = 0;
      // strcpy(e.Name,"D");
      // e.NeedRunningTime = 2;
      // e.Priority = GetPriority(&e, PR);
      // if(PR == SPF) e.ArrivalTime = 0;
      // GetProcess(*pPCBdata,e);
      //
      // e.ArrivalTime = 4;
      // e.ProcessState = Ready;
      // e.TimeUsedCPU = 0;
      // strcpy(e.Name,"E");
      // e.NeedRunningTime = 4;
      // e.Priority = GetPriority(&e, PR);
      // if(PR == SPF) e.ArrivalTime = 0;
      // GetProcess(*pPCBdata,e);
      //}
      int main(void)
      {
       LinkList PCBQueue;	//InitPCBdata里面存放PCB初始数据
       ElemType e = {{0},-1,-1,-1,-1,-1,0,Ready};
       ElemType *pcb = NULL;
       PriorityRule PR;
       PR = FCFS; // SPF or FCFS
      //*********** 初始化就绪队列 *************//
       Init(&PCBQueue);
       InputData(&PCBQueue, PR);
      printf("初始数据如下:\n");
       PrintProQueue(PCBQueue, pcb);
      //*********** 进程根据优先级上CPU *************//
      printf("\n进程运行信息如下:\n");
      while (OutProsess(PCBQueue, &e))
       {
      //一次性运行完毕
      while(e.TimeUsedCPU < e.NeedRunningTime)	//上完CPU的进程是否完毕
       {
       CPURunPro(PCBQueue, &e); //上CPU
       ++CPUUsedTime; //CPU时间增加
       }
      //*********** 当进程执行完毕时打印输出 *************//
       e.FinishTime = CPUUsedTime;
       PrintProResult(&e);
       }
      	getchar();
      return 0;
      }
  
 

 

文章来源: fantianzuo.blog.csdn.net,作者:兔老大RabbitMQ,版权归原作者所有,如需转载,请联系作者。

原文链接:fantianzuo.blog.csdn.net/article/details/102887367

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。