功能
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;elseprintf("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;
}
?