计算机操作系统实验报告-c语言版:
一.进程调度算法
1.实验名称:
进程调度算法
2.实验目的:
调度的实质是操作系统按照某种预定的策略来分配资源。进程调度的目的是分配CPU资源。由于进程调度程序执行的频率很高,因此调度算法的好坏直接影响到操作系统的性能。本实验的目的是编程模拟实现几种常用的进程调度算法,通过对几组进程分别使用不同的调度算法,计算进程的平均周转时间和平均带权周转时间,比较各种算法的性能优劣。
3.实验原理:
1.进程调度算法描述
进程调度算法包括先来先服务调度算法、优先数调度算法、时间片轮转算法3种。
先来先服务(FCFS)调度算法
本算法在进行调度时,总是把处理机分配给最先进入就绪队列的进程,一个进程一旦分得处理机,便一直执行下去,直到该进程完成或阻塞时,才释放处理机。
优先数调度算法
基于优先级的调度算法给每个进程分配一个优先级,在每次进程调度时,调度器总是调度那个具有最高优先级的任务来执行。如果就绪队列中出现优先数相同的进程,则对这些有相同优先数的进程采用FCFS算法调度。
时间片轮转(RR)调度算法
前几种算法主要用于批处理系统中,不能作为分时系统中的主调度算法,在分时系统中,都采用时间片轮转法。简单轮转法:系统将所有就绪进程按FIFO规则排队,按一定的时间间隔把处理机分配给队列中的进程。这样,就绪队列中所有进程均可获得一个时间片的处理机而运行。时间片用完,调度程序自动停止该进程的执行,将它放到进程就绪队列的末尾,等待下一次执行,然后将处理机分配给就绪队列中新的队首进程,也让它执行一个时间片。重复这个过程,直到所有的进程执行完毕。
4.仪器与材料:
PC机,Devc++。
5.实验步骤(代码):
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct PCB
{
char name[100]; // 进程名称
int executionTime; // 执行时间
int readyQueueTime; // 进入就绪队列的时间
int startTime; // 开始执行的时间
int endTime; // 结束执行的时间
int priority; // 优先级
};
// 打印进程信息的函数
void printProcessInfo(struct PCB *process)
{
double turnaroundTime = process->endTime - process->readyQueueTime;
double weightedTurnaroundTime = turnaroundTime / process->executionTime;
printf("进程名: %s\n", process->name);
printf("开始时间: %d\n", process->startTime);
printf("结束时间: %d\n", process->endTime);
printf("周转时间: %.2f\n", turnaroundTime);
printf("带权周转时间: %.2f\n", weightedTurnaroundTime);
printf("-----------------------------------\n");
}
// 先来先服务(FCFS)调度算法
void FCFS(struct PCB *processes, int size)
{
int currentTime = 0;
double totalTurnaroundTime = 0;
double totalWeightedTurnaroundTime = 0;
for (int i = 0; i < size; i++)
{
struct PCB *process = &processes[i];
process->startTime = currentTime;
process->endTime = currentTime + process->executionTime;
currentTime = process->endTime;
totalTurnaroundTime += process->endTime - process->readyQueueTime;
totalWeightedTurnaroundTime += (process->endTime - process->readyQueueTime) / (double)process->executionTime;
printProcessInfo(process);
}
double averageTurnaroundTime = totalTurnaroundTime / size;
double averageWeightedTurnaroundTime = totalWeightedTurnaroundTime / size;
printf("平均周转时间: %.2f\n", averageTurnaroundTime);
printf("平均带权周转时间: %.2f\n", averageWeightedTurnaroundTime);
}
// 优先级调度算法
void priorityScheduling(struct PCB *processes, int size)
{
int currentTime = 0;
float totalTurnaroundTime = 0;
float totalWeightedTurnaroundTime = 0;
// 根据优先级对进程进行排序
for (int i = 0; i < size - 1; i++)
{
for (int j = 0; j < size - i - 1; j++)
{
if (processes[j].priority > processes[j + 1].priority)
{
struct PCB temp = processes[j];
processes[j] = processes[j + 1];
processes[j + 1] = temp;
}
}
}
// 按优先级顺序执行进程
for (int i = 0; i < size; i++)
{
struct PCB *process = &processes[i];
process->startTime = currentTime;
process->endTime = currentTime + process->executionTime;
currentTime = process->endTime;
totalTurnaroundTime += process->endTime - process->readyQueueTime;
totalWeightedTurnaroundTime += (process->endTime - process->readyQueueTime) / (float)process->executionTime;
printProcessInfo(process);
}
float averageTurnaroundTime = totalTurnaroundTime / size;
float averageWeightedTurnaroundTime = totalWeightedTurnaroundTime / size;
printf("平均周转时间: %.2f\n", averageTurnaroundTime);
printf("平均带权周转时间: %.2f\n", averageWeightedTurnaroundTime);
}
// 轮转调度(RR)算法
void RR(struct PCB *processes, int size, int timeSlice)
{
int currentTime = 0;
float totalTurnaroundTime = 0;
float totalWeightedTurnaroundTime = 0;
struct PCB readyQueue[100];
int front = 0;
int rear = 0;
// 使用进程初始化就绪队列
for (int i = 0; i < size; i++)
{
processes[i].readyQueueTime = currentTime;
readyQueue[rear++] = processes[i];
}
// 以轮转方式执行进程
while (front != rear)
{
struct PCB process = readyQueue[front++];
if (process.executionTime <= timeSlice)
{
process.startTime = currentTime;
process.endTime = currentTime + process.executionTime;
currentTime = process.endTime;
totalTurnaroundTime += process.endTime - process.readyQueueTime;
totalWeightedTurnaroundTime += (process.endTime - process.readyQueueTime) / (float)process.executionTime;
printProcessInfo(&process);
}
else
{
process.startTime = currentTime;
currentTime += timeSlice;
process.executionTime -= timeSlice;
process.readyQueueTime = currentTime;
readyQueue[rear++] = process;
}
}
float averageTurnaroundTime = totalTurnaroundTime / size;
float averageWeightedTurnaroundTime = totalWeightedTurnaroundTime / size;
printf("平均周转时间: %.2f\n", averageTurnaroundTime);
printf("平均带权周转时间: %.2f\n", averageWeightedTurnaroundTime);
}
int main()
{
int c;
struct PCB processes[100];
FILE *inputFile = fopen("data.txt", "r");
if (inputFile != NULL)
{
int i = 0;
// 从文件中读取进程信息
while (fscanf(inputFile, "%s %d %d %d", processes[i].name, &processes[i].readyQueueTime,
&processes[i].executionTime, &processes[i].priority) == 4)
{
i++;
}
fclose(inputFile);
int size = i;
while (1)
{
printf("-----------------------------------------\n");
printf("1. FCFS调度算法\n");
printf("2. 优先级调度算法\n");
printf("3. RR调度算法\n");
printf("4. 结束程序\n");
printf("请输入序号选择所需的算法: ");
scanf("%d", &c);
if (c == 4)
break;
system("cls");
switch (c)
{
case 1:
printf("FCFS 调度算法结果\n");
FCFS(processes, size);
printf("\n");
system("pause");
system("cls");
break;
case 2:
printf("优先级调度算法结果\n");
priorityScheduling(processes, size);
printf("\n");
system("pause");
system("cls");
break;
case 3:
printf("RR调度算法结果\n");
int timeSlice;
printf("输入时间片大小(请输入不为零的整数): ");
scanf("%d", &timeSlice);
RR(processes, size, timeSlice);
system("pause");
system("cls");
break;
default:
break;
}
}
}
else
{
printf("无法打开文件.\n");
return 0;
}
return 0;
}
6.问题即讨论
该代码实现了三种调度算法:先来先服务(FCFS)、优先级调度和轮转调度(RR)。它从名为"data.txt"的文件中读取进程信息,并允许用户选择要执行的调度算法。代码还计算并打印了每个进程的周转时间、带权周转时间以及整个进程集合的平均指标。
在代码同目录下创建data.txt文本文件,每一行依次输入进程名,开始时间,结束时间,周转时间。运行代码,输入对应的算法序号,即可得到结果。
7.运行结果