实验一 进程调度算法
一、实验目的
应用高级语言编写和调试一个进程调度程序,通过创建进程、调度进程,进一步熟悉操作系统的进程概念,以加深进程调度算法的理解.
二、实验环境: 硬件环境:计算机一台,局域网环境; 软件环境:C语言编译器
三、实验指导: 设计一个有 N个进程共行的进程调度程序。
进程调度算法:分别采用先来先服务算法、短作业优先算法实现。
提示:
在采用短作业优先算法和高响应比优先算法进行调度时应注意进程的到达时间,对于没有到达的进程不应参与调度。
四、实验步骤(含流程图,实验过程分析等)
定义一个叫做process的结构体数组,结构体的属性包括进程的到达时间(Atime)、开始执行时间(Gtime)、结束时间(Etime)、服务时间(Stime)、周转时间(cycletime)、状态(status);
先来先服务(FCFS) 先来先服务:根据进程到达就绪队列的时间先后,到达早的进程先获得cpu,和进程的优先级和长短,紧迫度无关。
步骤一:定义一个函数CIN(int n),此函数的作用是用来输入进程的信息的;
步骤二:定义了两个排序函数,采用冒泡排序法分别对到达时间和短进程进行排序. 步骤三:定义函数FCFS(int n):函数FCFS接受到进程的个数,atimesort函数将进程数组M中的进程按照到达的时间从小到大进行排序。之后计算进程的到达时间和进程的完成时间。至于进程的开始执行时间分为两种情况,一是:下一个进程到达时,上一个进程还没有执行完成,此时这个进程的开始执行时间等于上一个进程的完成时间;二是:下一个进程到达时,上一个进程已经执行完成,CPU处于空闲状态,此时此进程的开始执行时间就等于进程的到达时间。进程的完成时间=进程的到达时间+进程的完成时间。
步骤四:定义函数SJF(int n):函数接收到进程的个数,循环判断到达时间是否满足当前时间noetime,如果满足则将结构体数组复制到等待函数中,在等待函数中进行短进程排序,然后循环判断输出第一个结构体函数.
平均周转时间:所有的进程的周转时间/进程个数;
带权周转时间:周转时间/服务时间
在系统的提示下,输入所要操作的进程数,函数CIN(int n)接受进程数,之后在系统的提示下输入所有的进程的相关信息。 开始计算第一个进程的相关的时间。
第一个进程的完成时间=进程的服务时间+进程的到达时间;
进程的周转时间(avtime)=进程的完成时间-进程的到达时间;
进程的带权周转时间=进程的周转时间/进程的服务时间;
计算除了第一个进程外的其他的进程的相关时间。
五、实验结果及分析
先来先服务:
(1) 在系统的提示下,输入进程的个数以及相关的信息。
分析:进程P2先到达,所以开始服务时间为3s,服务时间为5s,完成时间为8s,在p2执行过程中p1到达,等待P2在8s完成时,P1开始执行。
(2)计算进程的带权周转时间、带权平均周转时间、周转时间、带权周转时间;
P1的周转时间:13-7=6s
P2的周转时间:8-3=5s
平均周转时间:(6+5)/2=5.5s
P1的带权周转时间:6/5=1.2s
P2的带权周转时间:5/5=1s
平均带权周转时间:(1+1.2)/2=1.1s
短进程优先:
六、实验源代码
#include<stdio.h>
#include<stdlib.h>
#define N 20
static int w = 0;
static int nowtime = 0;
struct process
{
int n ;//进程数
char name[50] ;//进程名
int atime ;//到达时间
int gtime ;//开始时间
int etime ;//结束时间
int stime ;//服务时间
int ctime ;//周转时间
double wtime;//带权周转
int status =0;//状态,,,0未到达,,,1等待
}M[N], N1[N];
void CIN(int n) {
for (int i = 0;i < n;i++) {
printf("输入第%d个进程的信息:\n", i + 1);
printf("请输入进程名:\n");
scanf("%s", M[i].name, sizeof(M[i].name));
printf("输入进程到达时间:\n");
scanf("%d", &M[i].atime);
printf("输入进程服务时间:\n");
scanf("%d", &M[i].stime);
}
}
void sortatime(process M[], int n) { //将进程按到达时间(atime)排序
int i, j;
process temp;
for (i = 1; i < n; i++) {
for (j = 0; j < n - i; j++) {
if (M[j].atime > M[j + 1].atime) {
temp = M[j];
M[j] = M[j + 1];
M[j + 1] = temp;
}
}
}
}
void sortstime(process M[], int n) { //将进程按服务时间(stime)排序
int i, j;
process temp;
for (i = 1; i < n; i++) {
for (j = 0; j < n - i; j++) {
if (M[j].stime > M[j + 1].stime) {
temp = M[j];
M[j] = M[j + 1];
M[j + 1] = temp;
}
}
}
}
void FCFS(int n) { //先来先服务
sortatime(M, n);
M[0].gtime = M[0].atime;
M[0].etime = M[0].gtime + M[0].stime;
M[0].ctime = M[0].etime - M[0].atime;
M[0].wtime = M[0].ctime/(1.00*M[0].stime);
for (int i = 1;i < n;i++) {
M[i].gtime = M[i].atime > M[i - 1].etime ? M[i].atime : M[i - 1].etime;
M[i].etime = M[i].gtime + M[i].stime;
M[i].ctime = M[i].etime - M[i].atime;
M[i].wtime = M[i].ctime/(1.00*M[i].stime);
}
}
void wait(int i) {
N1[w] = M[i];
w++;
sortstime(N1, w);
}
void printwait() {
if (N1[0].status == 1) {
N1[0].gtime = nowtime;
N1[0].etime = N1[0].gtime + N1[0].stime;
N1[0].ctime = N1[0].etime - N1[0].atime;
N1[0].wtime = N1[0].ctime/(1.00*N1[0].stime);
nowtime = N1[0].etime;
printf("%3s\t%4d\t%6d\t%8d\t%4d\t%6d\t %9.3lf\n", N1[0].name, N1[0].atime, N1[0].gtime, N1[0].etime, N1[0].stime, N1[0].ctime,N1[0].wtime);
for (int i = 0;i < w;i++) {
N1[i] = N1[i + 1];
}
w--;
}
}
void SJF(int n) { //短进程优先
int count = n, flag = 0;
printf("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n");
printf("进程名 到达时间 开始时间 结束时间 服务时间 周转时间 带权周转时间\n");
while (count > 0) {
for (int i = 0;i < n;i++) {
if (M[i].atime <= nowtime && M[i].status == 0) {
M[i].status = 1; //进入等待
wait(i);
count--;
flag = 1;
}
}
if (w > 0) {
for (int i = -1;i < w;i++) {
printwait();
}
}
if (flag == 0) {
nowtime++;
}
flag = 0;
}
for (int i = 0;i < n;i++) {
M[i].status = 0;
}
nowtime = 0;
}
//等待区域,存一次-》短进程排序打印一次,返回判断到达时间-》重复-》直到全部到达-》短进程排序-》打印
void print(int n) {
printf("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n");
printf("进程名 到达时间 开始时间 结束时间 服务时间 周转时间 带权周转时间\n");
for (int i = 0;i < n;i++) {
printf("%3s\t%4d\t%6d\t%8d\t%4d\t%6d\t %9.3lf\n", M[i].name,M[i].atime, M[i].gtime, M[i].etime, M[i].stime, M[i].ctime, M[i].wtime);
}
}
void menu(int n) {
printf("~~~~~~~~~~~~请选择算法~~~~~~~~~~~~~~~~~\n");
printf("请选择算法\n");
printf("1.先来先服务\n");
printf("2.短进程优先\n");
printf("3.退出\n");
printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
int m = 0;
while (m != 3) {
printf("请选择:");
scanf("%d", &m);
if (m == 1) {
FCFS(n);
print(n);
}
if (m == 2) {
SJF(n);
}
if (m == 3) {
exit(0);
}
if (m < 1 || m>3) {
printf("输入错误\n");
}
}
}
int main() {
int n;
printf("请输入进程个数:");
scanf("%d", &n);
CIN(n);
while(1){
menu(n);
}
return 0;
}