目录
一、实验目的与要求
- 加深对作业/进程调度算法的理解;
- 进行程序设计的训练;
- 学会使用高级语言编写一个或多个算法的模拟程序。
二、实验环境
Ubuntu、centos、Windows系统
三、实验内容
使用c语言完成FCFS算法的模拟,先来先服务算法按照作业或进程到达时间的先后排队,依次等待调度。
每个进程由一个进程控制块PCB表示,包含以下信息:进程名、进程ID、提交(到达)系统时间、开始时间、运行时间、完成时间、进程状态(就绪、阻塞、执行)等。
1.模拟数据生成
允许用户指定进程的个数(5-25个),默认5个。
允许用户选择输入每个进程的到达时间和所需运行时间。
2.模拟程序的功能
以表格形式打印显示出每个进程(正在运行进程和等待进程)的进程名、到达时刻、开始运行时刻、结束运行时刻、现在系统时刻、进程状态、所需运行时间。
指出进程到达顺序与调度顺序,并计算每个进程的周转时间和带权周转时间。
3 .数据及算法分析
对同一批进程、改变进程的到达顺序、分析先来先服务算法的优缺点。
4.完成实验报告
对相关代码和过程进行保存,并对相关实验结果截图展示在实验报告中,其中代码部分需粘贴在实验报告中不要截图请直接贴代码。
四、实验过程
1. 计划进行FCFS算法的模拟。使用先来先服务算法按照作业或进程到达时间的先后排队,依次等待调度。
2.生成模拟数据。允许用户指定进程的个数(5-25个),默认5个。允许用户选择输入每个进程的到达时间和所需运行时间。
3.模拟程序的功能。以表格形式打印显示出每个进程(正在运行进程和等待进程)的进程名、到达时刻、开始运行时刻、结束运行时刻、现在系统时刻、进程状态、所需运行时间。指出进程到达顺序与调度顺序,并计算每个进程的周转时间和带权周转时间。
4. 分析实验数据及算法。对同一批进程、改变进程的到达顺序、分析先来先服务算法的优缺点。
5. 完成实验报告。对相关代码和过程进行保存,并对相关实验结果截图展示,直接贴上实验代码。
五、实验结果展示
1.实验参考结果(1)
2.实验参考代码(1)
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
//FCFS调度算法模拟
struct process {
//进程名称
char name[10];
//进程id
int id;
//进程到达时间
int arrivetime;
//进程开始时间
int starttime;
//进程运行时间
int runtime;
//进程完成时间
int finishtime;
//周转时间
float total;
//带权周转时间(周转系数)
float waitetime;
}PCB[25];
}
printf("\n");
for (i = 0; i < num; i++)
{
printf("请输入第%d个进程id、name、到达时间、所需运行时间。(数据间用空格间隔)\n", i + 1);
scanf("%d", &PCB[i].id);
scanf("%s", PCB[i].name);
scanf("%d", &PCB[i].arrivetime);
scanf("%d", &PCB[i].runtime);
}
//按照到达时间进行排序
struct process t;
for (i = 0; i < num - 1; i++)
{
for (j = i + 1; j < num; j++)
{
if (PCB[i].arrivetime > PCB[j].arrivetime)
{
t = PCB[i];
PCB[i] = PCB[j];
PCB[j] = t;
}
}
}
//计算开始和完成时间
int nowtime = 0;
for (i = 0; i < num; i++)
{
//开始时间=当前时间=0
PCB[i].starttime = nowtime;
//完成时间=开始时间+运转时间
PCB[i].finishtime = PCB[i].starttime + PCB[i].runtime;
//周转时间=完成时间-到达时间
PCB[i].total = PCB[i].finishtime - PCB[i].arrivetime;
//带权周转时间=周转时间/运行时间
PCB[i].waitetime = PCB[i].total / PCB[i].runtime;
//当前时间=完成时间
nowtime = PCB[i].finishtime;
}
//进程开始运行
printf("\n");
for (i = 0; i < num; i++)
{
printf("进程%s开始运行......\n", PCB[i].name);
}
//显示进程表格
printf("\n");
printf(" id 进程名 到达时间 开始时间 结束时间 周转时间 带权周转时间\n");
for (i = 0; i < num; i++)
{
printf("%5d %5s %5d %8d %8d %.6f %.6f\n", PCB[i].id, PCB[i].name, PCB[i].arrivetime, PCB[i].starttime, PCB[i].finishtime, PCB[i].total, PCB[i].waitetime);
}
return 0;
}
3.实验参考结果(2)
4.实验参考代码(2)
#include "stdio.h"
typedef struct
{
//struct PCB* link; //PCB链表指针
char name; //进程名
int id; //进程id
int atime; //进程到达时间
int stime; //进程开始时间
int runtime; //进程运行时间
int ftime; //进程完成时间
float total; //周转时间
float welght; //带权周转时间(周转系数)
int status; //进程状态
}PCB;
enum bool{false = 0,true = 1 };
void init(PCB p[],int n){//初始化进程
//printf("请输入进程个数\n");
//scanf("%d",&n);
int i;
for(i=0;i<n;i++){
printf("请输入第%d个进程的id、name、到达时间、所需运行时间。数据间用空格间隔\n",i+1);
scanf("%d %c %d %d",&p[i].id,&p[i].name,&p[i].atime,&p[i].runtime);
p[i].status=1;//1代表就绪
}
}
void sort(PCB p[],int n){//对进程按照到达时间先后排序
int i,j;
enum bool change;
PCB temp;
for(i=0;i<n;i++){
change = false;
for(j=0;j<n-i-1;j++){
if(p[j].atime>p[j+1].atime){
temp=p[j];
p[j]=p[j+1];
p[j+1]=temp;
change = true;
}
}
if(!change)
return ;
}
}
void process(PCB p[],int n){//开始进程调度
int i;
for(i=0;i<n;i++){
printf("进程%c开始运行……\n",p[i].name);
if(i==0){
p[i].stime=p[i].atime;
}else{
p[i].stime=p[i-1].ftime;
}
p[i].ftime=p[i].stime+p[i].runtime;
p[i].status=2;//运行状态
p[i].total=(float)p[i].ftime-p[i].atime;
p[i].welght=p[i].total/p[i].runtime;
}
}
void print(PCB p[],int n){
int i;
printf("id 进程名 到达时间 运行时间 开始时间 结束时间 周转时间 带权周转时间\n");
for(i=0;i<n;i++){
printf("%d %c %d %d %d %d %f %f\n",p[i].id,p[i].name,p[i].atime,p[i].runtime,p[i].stime,p[i].ftime,p[i].total,p[i].welght);
}
}
int main(){
PCB p[25];
int n=0;
printf("请输入进程个数\n");
scanf("%d",&n);
init(p,n);
sort(p,n);
//print(p,n);
process(p,n);
print(p,n);
return 1;
}
六、实验总结和思考
编写代码时,我发现自己对C语言的基础知识已经不太熟悉了,并且,自己对FCFS的算法没有进行过深入的探究和学习。因此,我要多找时间去巩固C语言基础知识,多研究FCFS算法等方面的内容,认真学习优秀的教程和代码,尽量在电脑上进行相关实践,使自己能够熟练地掌握这方面编程知识。
而且,当代码运行出现问题时,在经过自己的认真思考和资料查找之后,应主动与同学还有老师进行交流,多制作出几套方案,以锻炼自己解决问题和与他人协作的能力。
总之,学无止境,我还有许许多多方面的能力都还需要提高,今后我会更加严格要求自己,加强自己的学习能力。