用C語言實現先來先服務FCFS程序排程演算法
阿新 • • 發佈:2018-12-09
**分析:**先來先服務的意思就是哪個程序先到就先進行哪個程序,只與來的先後次序有關,等第一個程序執行完之後才會程序下一個程序的執行。
- 只有第一個程序的開始時間是它的到達時間,後邊的程序開始時間都是前一個進的完成時間。
- 完成時間就等於該程序的開始時間加上服務時間
- 週轉時間 = 完成時間 - 到達時間
- 帶權週轉時間 = 週轉時間 / 服務時間
我們可以採用連結串列把這些程序資訊儲存起來,當第一個程序(結點)結束後,再進行下一個程序(結點)。我這裡採用的是頭插方法,結點插入完成後,最後一個程序是當前的頭結點,所以要進行連結串列反轉,將連結串列順序轉回來,這樣才能計算正確。
程式碼如下:
test.c
#define _CRT_SECURE_NO_WARNINGS 1
#include"os.h"
int main()
{
_PCB* pcb;
InitPcb(&pcb);//初始化函式
printf("程序名\t到達時間\t服務時間\n");
Input(&pcb);//插入結點
OrderServer(_PCB** pcb);//核心演算法
return 0;
}
os.c
void InitPcb(_PCB** pcb) { assert(pcb); if (NULL == (*pcb)) return; (*pcb) = NULL; } _PCB* BuyNode(_PCB* pcb) { _PCB* newNode = (_PCB*)malloc(sizeof(_PCB)); if (NULL == newNode) return NULL; else { setbuf(stdin, NULL); scanf("%c %d %d", &newNode->Name, &newNode->ArriveTime, &newNode->ServerTime); newNode->next = NULL; return newNode; } } void PushFront(_PCB** pcb)//頭插 { _PCB* cur = NULL; assert(pcb); if (*pcb == NULL) { (*pcb) = BuyNode(*pcb); return; } else { cur = BuyNode(*pcb); cur->next = (*pcb); (*pcb) = cur; } } void Input(_PCB** pcb) { int i = 0; for (i = 0; i < MAX; i++) { PushFront(pcb); } } void Print(_PCB** pcb) { _PCB* cur = NULL; cur = (*pcb); assert(pcb); if (NULL == (*pcb)) return; printf("程序名\t到達時間\t服務時間\t開始執行時間\t完成時間\t週轉時間\t帶權週轉時間\n"); while (cur) { printf("%c\t%d\t%d\t%d\t%d\t%d\t%f\n", cur->Name, cur->ArriveTime, cur->ServerTime, cur->StartTime, cur->FinishTime, cur->WholeTime, cur->ValueWholeTime); cur = cur->next; } } void Turn(_PCB** pcb)//反轉連結串列 { _PCB* cur = (*pcb); _PCB* pre = cur->next; _PCB* pb = pre->next; assert(pcb); if (NULL == pcb) return; cur->next = NULL; while (pre && pb) { pre->next = cur; cur = pre; pre = pb; pb = pb->next; } pre->next = cur; (*pcb) = pre; } void OrderServer(_PCB** pcb) { _PCB* cur = NULL; _PCB* pre = NULL;//用來記錄前一個結點,計算開始執行時間需要用到前一個結點的資訊 Turn(pcb); cur = pre = (*pcb); assert(pcb); int i = 0;//記錄當前是第幾個程序 if (NULL == (*pcb)) return; while (cur) { if (0 == i || 1 == i)//說明是第一個/第二個程序 { if (0 == i) { cur->StartTime = cur->ArriveTime; i++; } else//是第二個程序,因為第二個程序的pre是頭結點,所以不需要移動,單獨出來 { cur->StartTime = pre->FinishTime; i++; } cur->FinishTime = cur->ServerTime + cur->StartTime; cur->WholeTime = cur->FinishTime - cur->ArriveTime; cur->ValueWholeTime = (float)cur->WholeTime / (float)cur->ServerTime; cur = cur->next; } else { pre = pre->next; cur->StartTime = pre->FinishTime; cur->FinishTime = cur->ServerTime + cur->StartTime; cur->WholeTime = cur->FinishTime - cur->ArriveTime; cur->ValueWholeTime = (float)cur->WholeTime / (float)cur->ServerTime; cur = cur->next; i++; } } }
os.h
#ifndef __OS_H__ #define __OS_H__ #include<stdio.h> #include<assert.h> #include<stdlib.h> #define MAX 4 typedef struct PCB{ char Name;//程序名 int ArriveTime;//到達時間 int ServerTime;//服務時間 int Time;//時間片 int Front;//優先順序 int StartTime;//開始執行時間 int FinishTime;//完成時間 int WholeTime;//週轉時間 float ValueWholeTime;//帶權週轉時間 int Ago;//標記當前結點有沒有被訪問過 struct PCB* next; int AddTime;//累加時間 int AtTime;//當前時刻 }_PCB; void InitPcb(_PCB** pcb);//初始化 _PCB* BuyNode(_PCB* pcb); void PushFront(_PCB** pcb);//頭插 void Input(_PCB** pcb);//輸入函式 void Print(_PCB** pcb);//列印 void OrderServer(_PCB** pcb);//先來先服務 void Turn(_PCB** pcb);//將連結串列翻轉過來
執行結果: