模拟进程调度

功能

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;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

兔老大RabbitMQ

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值