【实验题目】
通过这次实验,加深对进程概念的理解,进一步掌握进程状态的转变、进程调度的策略及对系统性能的评价方法。
【实验内容】
设计程序模拟进程的先来先服务FCFS和短作业优先SJF调度过程。假设有n个进程分别在T1, … ,Tn时刻到达系统,它们需要的服务时间分别为S1, … ,Sn。分别采用先来先服务FCFS和短作业优先SJF进程调度算法进行调度,计算每个进程的完成时间,周转时间和带权周转时间,并且统计n个进程的平均周转时间和平均带权周转时间。
注:
周转时间=作业完成时刻—作业到达时刻;
带权周转时间=周转时间/服务时间;
平均周转时间=作业周转总时间/作业个数;
平均带权周转时间=带权周转总时间/作业个数;
【实验要求】
- 进程个数n;每个进程的到达时间T1, … ,Tn和服务时间S1, … ,Sn;选择算法1-FCFS,2-SJF。
- 要求采用先来先服务FCFS和短作业优先SJF分别调度进程运行,计算每个进程的周转时间,带权周转时间,并且计算所有进程的平均周转时间,带权平均周转时间;
- 输出:要求模拟整个调度过程,输出每个时刻的进程运行状态,如“时刻3:进程B开始运行”等等;
- 输出:要求输出计算出来的每个进程的周转时间,带权周转时间,所有进程的平均周转时间,带权平均周转时间。
【C语言程序代码】
#include<stdio.h>
#define Max 100
//定义全局变量
int ArrivalTime[Max];//到达时间
int ServiceTime[Max];//服务时间
int FinishTime[Max];//完成时间
int AroundTime[Max];//周转时间
double QAroundTime[Max];//带权周转时间
//全局int数组默认值0,double默认0,非全局数组初值是机器垃圾值
//全局变量或者静态变量,未初始化是0.局部变量,是以前残留在堆栈里的随机值
double AvgFCFSTime;//FCFS平均周转时间
double AvgSJFTime;//SJF平均周转时间
double AvgQFCFSTime, AvgQSJFTime;//FIFC平均带权周转时间, SJF平均带权周转时间
int n;
//输入
void Input() {
printf("请输入作业个数(进程数n):\n");
scanf("%d", &n);
// printf("input %d",n);
printf("请分别输入每个进程的到达时间:\n");
for (int i = 0; i < n; i++) {
scanf("%d", &ArrivalTime[i]);//到达时间
}
printf("请分别输入每个进程的服务时间:\n");
for (int i = 0; i < n; i++) {
scanf("%d", &ServiceTime[i]);//服务时间
}
}
//陈列
void Show() {
printf("******************************************************\n");
// printf("show %d",n);
printf("进程的相关信息如下所示:\n");
printf("进程名 ");//3个空格
printf("到达时间 ");
printf("服务时间 ");
printf("完成时间 ");
printf("周转时间 ");
printf("带权周转时间 \n");
for (int i = 0; i < n; i++) {
//此处的n有错误
printf(" %-8d", i + 1);//进程名
printf(" %-8d", ArrivalTime[i]);//到达时间
printf(" %-10d", ServiceTime[i]);//服务时间
printf(" %-10d", FinishTime[i]);//完成时间
printf(" %-10d", AroundTime[i]);//周转时间
printf(" %-8.1f\n", QAroundTime[i]);//带权周转时间
}
}
//FCFS算法
/*
按照到达顺序,依次执行
*/
void FCFS() {
int first = Max;
int m, k;
//按到达先后次序排序(此处代码未优化)
for (int i = 0; i < n; i++) {
for (int l = 0; l < n; l++) {
if (ArrivalTime[l] < ArrivalTime[first]) {
first = l;
m = ArrivalTime[i];
k = ServiceTime[i];
ArrivalTime[i] = ArrivalTime[first];
ServiceTime[i] = ServiceTime[first];
ArrivalTime[first] = m;
ServiceTime[first] = k;
}
}
}
//进程时间计算
for (int j = 0; j < n; j++) {
if (j == 0)
FinishTime[j] = ArrivalTime[j] + ServiceTime[j];
else
FinishTime[j] = FinishTime[j - 1] + ServiceTime[j];//完成时间
AroundTime[j] = FinishTime[j] - ArrivalTime[j];//周转时间
QAroundTime[j] = (double)AroundTime[j] / (double)ServiceTime[j];//带权周转时间
}
double sum1 = 0, sum2 = 0;//平均周转时间,平均带权周转时间
for (int q = 0; q < n; q++) {
sum1 += AroundTime[q];
sum2 += QAroundTime[q];
}
AvgFCFSTime = sum1 / n;
AvgQFCFSTime = sum2 / n;
Show();//调用函数输出列表
printf("平均周转时间=%.1f\n", AvgFCFSTime);
printf("平均带权周转时间=%.1f\n", AvgQFCFSTime);
printf("******************************************************");
}
void SJF()
{
// printf("进入sjf");
int first = Max;
int m, k;
//按到达先后次序排序
for (int i = 0; i < n; i++) {
for (int l = 0; l < n; l++) {
if (ArrivalTime[l] < ArrivalTime[first]) {
first = l;
m = ArrivalTime[i];
k = ServiceTime[i];
ArrivalTime[i] = ArrivalTime[first];
ServiceTime[i] = ServiceTime[first];
ArrivalTime[first] = m;
ServiceTime[first] = k;
}
}
}
//第一个进程时间计算
int j = 0, startWorkTime = 0;
FinishTime[j] = ArrivalTime[j] + ServiceTime[j];
AroundTime[j] = FinishTime[j] - ArrivalTime[j];//周转时间
QAroundTime[j] = (double)AroundTime[j] / ServiceTime[j];//带权周转时间
startWorkTime += ServiceTime[0]; //下一个进程的开始执行时间
bool isFinished_SJF[Max];
for (int q = 0; q < n; q++)
{
isFinished_SJF[q] = false;
}
isFinished_SJF[0] = true;
int nextProcess = n;
for (int i = 0; i < n; i++)
{
nextProcess = n;
for (int b = 0; b < n; b++)
{
if (ArrivalTime[b] <= startWorkTime&&!isFinished_SJF[b]) //在任务完成之前到达
{
if (nextProcess == n)
{
nextProcess = b;
}
if (ServiceTime[nextProcess] > ServiceTime[b])
{
nextProcess = b; //获得运行时间最短的作业的下标
}
}
}
//对获得的进程进行处理
isFinished_SJF[nextProcess] = true;
FinishTime[nextProcess] = ServiceTime[nextProcess] + startWorkTime;
startWorkTime += ServiceTime[nextProcess];
AroundTime[nextProcess] = FinishTime[nextProcess] - ArrivalTime[nextProcess];
QAroundTime[nextProcess] = (double)AroundTime[nextProcess] / ServiceTime[nextProcess];
}
double sum1 = 0, sum2 = 0;//平均周转时间,平均带权周转时间
for (int q = 0; q < n; q++) {
sum1 += AroundTime[q];
sum2 += QAroundTime[q];
}
AvgFCFSTime = sum1 / n;
AvgQFCFSTime = sum2 / n;
Show();//调用函数输出列表
printf("平均周转时间=%.1f\n", AvgFCFSTime);
printf("平均带权周转时间=%.1f\n", AvgQFCFSTime);
printf("******************************************************");
}
void Chose() {
printf("请选择算法“1-FCFS,2-SJF”\n");
int choose;
scanf("%d", &choose);
if (choose == 1) {
FCFS();
}
else if (choose == 2) {
SJF();
}
else {
printf("请输入正确的选择“1-FCFS,2-SJF”\n");
printf("******************************************************\n");
Chose(); //递归调用,继续运行
}
}
int main() {
Input();
Chose();
return 0;
程序测试
请输入作业个数(进程数n):
5
请分别输入每个进程的到达时间:
0 1 2 3 4
请分别输入每个进程的服务时间:
5 3 2 1 4
请选择算法“1-FCFS,2-SJF”
1
请输入作业个数(进程数n):
5
请分别输入每个进程的到达时间:
0 1 2 3 4
请分别输入每个进程的服务时间:
5 3 2 1 4
请选择算法“1-FCFS,2-SJF”
2