提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录
一、FCFS算法思路与代码部分
二、SJF算法思路与代码部分
三、全部代码
前言
本文用于记录我的操作系统实验一 只用了c++的cout cin语句 基本都是c。
文中定义进程为一结构体(已知条件为到达时间cometime与服务时间servetime):
typedef struct pcb
{
char id;//进程id
int cometime;//到达时间
int servetime;//服务时间
int starttime;//开始时间
int endtime;//结束时间
int cycletime;//周转时间
float powertime;//带权周转时间
};
一、FCFS算法思路与代码部分
FCFS(First come first serve)即先到先服务,以到达时间为基准,哪个进程的到达时间小就先服务,不过对于第i+1个进程的到达时间在第i个进程的完成时间之前还是之后要进行分类讨论。
首先是按到达时间排序(小的在前):
void sort_time(pcb p[], int n)//冒泡排序(按到达时间
{
int i, j;
pcb t;//中间变量
for (i = 0; i < n - 1; i++)
{
for (j = i + 1; j <= n-1; j++)
if (p[i].cometime > p[j].cometime)
{
t = p[i];
p[i] = p[j];
p[j] = t;
}
}
}
排完序后对于第一个到达的进程服务(即计算第一个进程的各种时间):
p[0].starttime = p[0].cometime;
p[0].endtime = p[0].starttime + p[0].servetime;
p[0].cycletime = p[0].endtime - p[0].cometime;
p[0].powertime = (p[0].cycletime * 1.0) / (p[0].servetime * 1.0);
接着就是遍历p[1]到p[n-1],进行分类讨论:
for (int i = 1; i <= n - 1; i++)
{
//若i-1还未完成时i就来了,则等待i-1完成
if (p[i].cometime < p[i - 1].endtime)
p[i].starttime = p[i - 1].endtime;
else
//i-1完成后经过一段空闲时间i来了,则直接服务
{
p[i].starttime = p[i].cometime;
p[i].endtime = p[i].starttime + p[i].servetime;
p[i].cycletime = p[i].endtime - p[i].cometime;
p[i].powertime = (p[i].cycletime * 1.0) / (p[i].servetime*1.0);
}
}
二、SJF算法思路与部分代码
SJF(short job first)短作业优先算法即在等待队列中谁的servetime短谁就先服务,若等待队列中没有进程则对下一个到达的进程服务。
我具体想法是先将所有进程中到达时间cometime最小的筛选出来与p[0]交换位置,
int k = 0;
pcb temp;
//找到最小的come
for (int i = 0; i < n; i++)
{
if (p[k].cometime > p[i].cometime)
k = i;
}
//找到后放到p[0]位置便于后续操作
temp = p[0];
p[0] = p[k];
p[k] = temp;
这个到达时间cometime最小的进程先服务
p[0].starttime = p[0].cometime;
p[0].endtime = p[0].starttime + p[0].servetime;
p[0].cycletime = p[0].endtime - p[0].cometime;
p[0].powertime = (p[0].cycletime * 1.0) / (p[0].servetime * 1.0);
然后将p[1]到p[n-1]按服务时间servetime进行排序
void sort_servetime(pcb p[], int n)//将进程按完成时间排序(冒泡)
{
int i, j;
pcb t;//中间变量
for (i = 1; i < n - 1; i++)
{
for (j = i + 1; j <= n-1; j++)
if (p[i].servetime > p[j].servetime)
{
t = p[i];
p[i] = p[j];
p[j] = t;
}
}
}
以上的为准备工作,接着设i为当前时刻服务完的进程,j为我们希望找到的下一个接受服务的进程(初值为i+1),对于每个i,遍历数组从i+1开始找寻j
//tag=0标志着对于刚完成的第i个进程,等待队列中啥都没(剩下的进程都还没到)
int tag = 0;
for (int i = 0; i < n; i++)
{
for (int j = i + 1; j < n; j++)
{
//等待队列中第一个进程先服务
if (p[j].cometime <= p[i].endtime)
{
//更新tag
tag = 1;
p[j].starttime = p[i].endtime;
p[j].endtime = p[j].starttime + p[j].servetime;
p[j].cycletime = p[j].endtime - p[j].cometime;
p[j].powertime = (p[j].cycletime * 1.0) / (p[j].servetime * 1.0);
//服务完后将进程往前移 利于后续操作
temp = p[j];
for (int k = j; k > i + 1; k--)
{
p[k] = p[k - 1];
}
p[i + 1] = temp;
break;
//若进程都不在等待 则谁先到达谁服务
if (tag = 0)
{
int n = i;
//找最小come
for (int m = i + 1; i < n; i++)
{
if (p[n].cometime > p[i].cometime)
n = i;
}
//此时n为最小come n服务
p[n].starttime = p[n].cometime;
p[n].endtime = p[n].starttime + p[n].servetime;
p[n].cycletime = p[n].endtime - p[n].cometime;
p[n].powertime = (p[n].cycletime * 1.0) / (p[n].servetime * 1.0);
//服务完后将进程往前移 利于后续操作
temp = p[n];
for (int k = n; k > i + 1; k--)
{
p[k] = p[k - 1];
}
p[i + 1] = temp;
break;
}
}
}
}
三、全部代码
#include <iostream>
using namespace std;
#include "stdio.h"
typedef struct pcb
{
char id;//进程id
int cometime;//到达时间
int servetime;//服务时间
int starttime;//开始时间
int endtime;//结束时间
int cycletime;//周转时间
float powertime;//带权周转时间
};
void sort_time(pcb p[], int n)//冒泡排序(按时间
{
int i, j;
pcb t;//中间变量
for (i = 0; i < n - 1; i++)
{
for (j = i + 1; j <= n-1; j++)
if (p[i].cometime > p[j].cometime)
{
t = p[i];
p[i] = p[j];
p[j] = t;
}
}
}
void calculate(pcb p[], int n)//计算进程的各种时间
{
p[0].starttime = p[0].cometime;
p[0].endtime = p[0].starttime + p[0].servetime;
p[0].cycletime = p[0].endtime - p[0].cometime;
p[0].powertime = (p[0].cycletime * 1.0) / (p[0].servetime * 1.0);
for (int i = 1; i <= n - 1; i++)
{
if (p[i].cometime < p[i - 1].endtime)
p[i].starttime = p[i - 1].endtime;
else
p[i].starttime = p[i].cometime;
p[i].endtime = p[i].starttime + p[i].servetime;
p[i].cycletime = p[i].endtime - p[i].cometime;
p[i].powertime = (p[i].cycletime * 1.0) / (p[i].servetime*1.0);
}
}
void sort_servetime(pcb p[], int n)//将进程按完成时间排序
{
int i, j;
pcb t;//中间变量
for (i = 1; i < n - 1; i++)
{
for (j = i + 1; j <= n-1; j++)
if (p[i].servetime > p[j].servetime)
{
t = p[i];
p[i] = p[j];
p[j] = t;
}
}
}
void FCFS(pcb p[], int n)
{
sort_time(p, n);//先将进程按到达时间排序
calculate(p, n);//计算各种时间
}
void SJF(pcb p[], int n)
{
int k = 0;
pcb temp;
//找到最小的come
for (int i = 0; i < n; i++)
{
if (p[k].cometime > p[i].cometime)
k = i;
}
temp = p[0];
p[0] = p[k];
p[k] = temp;
sort_servetime(p, n);//先按serve时间排序
//先服务
p[0].starttime = p[0].cometime;
p[0].endtime = p[0].starttime + p[0].servetime;
p[0].cycletime = p[0].endtime - p[0].cometime;
p[0].powertime = (p[0].cycletime * 1.0) / (p[0].servetime * 1.0);
int tag = 0;
for (int i = 0; i < n; i++)
{
for (int j = i + 1; j < n; j++)
{
//等待队列中第一个进程先服务
if (p[j].cometime <= p[i].endtime)
{
tag = 1;
p[j].starttime = p[i].endtime;
p[j].endtime = p[j].starttime + p[j].servetime;
p[j].cycletime = p[j].endtime - p[j].cometime;
p[j].powertime = (p[j].cycletime * 1.0) / (p[j].servetime * 1.0);
//服务完后将进程往前移
temp = p[j];
for (int k = j; k > i + 1; k--)
{
p[k] = p[k - 1];
}
p[i + 1] = temp;
break;
//若进程都不在等待 则谁先到达谁服务
if (tag = 0)
{
int n = i;
//找最小come
for (int m = i + 1; i < n; i++)
{
if (p[n].cometime > p[i].cometime)
n = i;
}
//此时n为最小come n服务
p[n].starttime = p[n].cometime;
p[n].endtime = p[n].starttime + p[n].servetime;
p[n].cycletime = p[n].endtime - p[n].cometime;
p[n].powertime = (p[n].cycletime * 1.0) / (p[n].servetime * 1.0);
//服务完后将进程往前移
temp = p[n];
for (int k = n; k > i + 1; k--)
{
p[k] = p[k - 1];
}
p[i + 1] = temp;
break;
}
}
}
}
}
//打印算法模拟结果的函数
void print(pcb p[], int n)
{
int i;
double averruntime;
double averdqzztime;
int sum_runtime = 0;
double sum_dqzztime = 0.00;
cout << "作业名\t\t到达时间\t运行时间\t完成时间\t周转时间\t带权周转时间\n";
for (i = 0; i < n; i++)
{
cout << p[i].id << "\t\t" << p[i].cometime << "\t\t" << p[i].servetime << "\t\t" << p[i].endtime << "\t\t" << p[i].cycletime << "\t\t" << p[i].powertime << endl;
sum_runtime = sum_runtime + p[i].cycletime;
sum_dqzztime = sum_dqzztime + p[i].powertime;
}
averruntime = sum_runtime * 1.0 / n;
averdqzztime = sum_dqzztime * 1.000 / n;
cout << "平均周转时间:" << averruntime << endl;
cout << "平均带权周转时间:" << averdqzztime << endl;
cout << endl;
}
void main()
{
pcb p[50];
int n, i;
cout << "输入作业个数:";
cin >> n;
cout << "输入每个作业的作业名,到达时间,服务时间:\n";
for (i = 0; i < n; i++)
{
cin >> p[i].id;
cin >> p[i].cometime;
cin >>p[i].servetime;
}
cout << endl;
cout << "初始值:" << endl;
cout << "作业名\t\t到达系统时间\t运行时间" << endl;
for (i = 0; i < n; i++)
{
cout << p[i].id << "\t\t" << p[i].cometime << "\t\t" << p[i].servetime << endl;
}
cout << endl;
FCFS(p, n);
cout << "先来先服务(FCFS)算法运行结果:" << endl;
SJF(p, n);
cout << "SJF运行结果:" << endl;
print(p, n);
}