一、原理
先来先服务(First Come First Serve,FCFS)调度算法是最简单的 CPU 调度算法之一,它按照作业到达的顺序为它们分配 CPU 时间。其原理如下:
- 任务到达:当一个任务(或进程)到达系统时,它被放入就绪队列的末尾,等待 CPU 的分配。
- CPU 分配:当 CPU 空闲时,调度程序从就绪队列中选择位于队列最前面的任务,将 CPU 分配给它。
- 任务执行:被选中的任务开始在 CPU 上执行,直到它完成或者发生某种中断。
- 任务完成:任务执行完毕后,如果有其他任务在就绪队列中,调度程序选择下一个任务来执行;否则,CPU 将保持空闲状态。
FCFS 调度算法的优点在于简单易实现,公平性强,每个任务都有机会被执行。然而,它也有一些缺点,比如无法适应长作业和短作业混合的情况,导致平均等待时间较长。
二、程序代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SIZE 30
typedef struct {
char ProcessName[100];
int Time;
int leval;
int LeftTime;
} Process;
void Copy(Process *proc1, Process *proc2);
void Sort(Process pr[], int size);
void Fcfs(Process pr[], int num, int TimePice);
int main() {
printf("\n");
printf("先来先服务调度算法:\n");
Process process[SIZE];
int num;
int TimePice;
printf("输入进程个数:\n");
scanf("%d", &num);
printf("输入进程时间片大小: \n");
scanf("%d", &TimePice);
for (int i = 0; i < num; i++) {
char name[100];
int CpuTime;
int Leval;
printf("输入第%d个进程的名字、cpu时间和优先级:\n", i + 1);
scanf("%s %d %d", name, &CpuTime, &Leval);
strcpy(process[i].ProcessName, name);
process[i].Time = CpuTime;
process[i].leval = Leval;
printf("\n");
}
for (int k = 0; k < num; k++)
process[k].LeftTime = process[k].Time;
printf("(在本程序所列进程信息中,优先级是指进程运行后的优先级!! )");
printf("\n\n");
printf("进程名字 需占用CPU时间 还需要占用时间 优先级 状态\n");
Fcfs(process, num, TimePice);
return 0;
}
void Copy(Process *proc1, Process *proc2) {
proc1->leval = proc2->leval;
strcpy(proc1->ProcessName, proc2->ProcessName);
proc1->Time = proc2->Time;
}
void Sort(Process pr[], int size) {
for (int i = 1; i < size; i++) {
Process temp;
temp = pr[i];
int j = i;
while (j > 0 && temp.leval < pr[j - 1].leval) {
pr[j] = pr[j - 1];
j--;
}
pr[j] = temp;
}
for (int d = size - 1; d > size / 2; d--) {
Process temp;
temp = pr[d];
pr[d] = pr[size - d - 1];
pr[size - d - 1] = temp;
}
}
void Fcfs(Process process[], int num, int Timepice) {
while (1) {
if (num == 0) {
printf("所有进程都已经执行完毕!\n");
exit(1);
}
if (process[0].LeftTime <= 0) {
printf("进程%s已经执行完毕!\n", process[0].ProcessName);
for (int i = 0; i < num; i++)
process[i] = process[i + 1];
num--;
} else if (process[num - 1].LeftTime <= 0) {
printf("进程%s已经执行完毕!\n", process[num - 1].ProcessName);
num--;
} else {
printf("\n");
process[0].LeftTime = process[0].LeftTime - Timepice;
process[0].leval = process[0].leval - 1;
printf("%s %d %d %d 运行\n",
process[0].ProcessName, process[0].Time,
process[0].LeftTime, process[0].leval);
for (int s = 1; s < num; s++) {
printf("%s %d %d %d 等待\n",
process[s].ProcessName, process[s].Time,
process[s].LeftTime, process[s].leval);
}
}
printf("\n");
system("pause");
printf("\n");
}
}
三、总结
在实验先来先服务调度算法的过程中:
- 理解调度算法的基本原理:通过实验,我更深入地理解了先来先服务调度算法的工作原理。这让我意识到了不同调度算法对系统性能和响应时间的影响。
- 掌握调度算法的实现方法:通过编写模拟程序或者观察现有系统的调度行为,我学会了如何实现先来先服务调度算法。这提高了我的编程能力和对操作系统的理解。
- 分析调度算法的优缺点:在实验中,我深入研究了先来先服务调度算法的优点和缺点。我意识到了它的简单性和公平性,但也发现了它可能导致的长作业等待时间过长的问题。
- 思考调度算法的改进:通过实验中的观察和分析,我开始思考如何改进调度算法以提高系统性能。这可能涉及到设计更复杂的调度算法或者结合多种算法来达到更好的平衡。