模拟实现操作系统进程调度
本程序介绍对于非抢占式多道批处理系统的进程调度算法
本程序在完成调度算法的基础上动态模拟实现了进程随时刻达到和结束的整个过程。
先来先服务原理分析:
每个进程都有自身的达到时间,在操作系统中,首先处理先到的进程,后到的进程需要等待先到达的进程运行完毕才能被执行。本程序在设计当中对于到到达时间相同的进程使用的处理办法是优先服务时间短较短的进程。
短进程优先原理分析:
首先在一开始就需要找到当前达到进程当中服务时间最短的进程,用于执行,在该进程执行当中,可能会有其他进程达到,这个过程中,不抢占当前正在运行的进程。等待该进程结束以后,又开始从所有当前时刻已到达(包括之前的就绪进程,不包括已执行)的进程当中寻找进程服务时间最短的进程用于执行,依照此法,直到所有进程执行完毕。本程序在设计当中对于当前时刻到达的所有进程,存在服务时间相同的情况处理为先到的进程先执行。
- 结束时间 = 到达时间 + 服务时间;
- 周转时间 = 结束时间 - 到达时间;
- 带权周转时间 = 周转时间 / 服务时间;
进程控制块(PCB)的定义:
struct PCB
{
char name;
float arrivetime; //达到时间
float servetime; //运行(服务)时间
float finishtime; //结束(完成)时间
float roundtime; //周转时间
float daiquantime; //带权周转时间
};
struct PCB a[100]; //结构体数组
主要变量说明:
int time = 0; //定义当前时刻
int jcnum = 0; //定义当前进程指向
struct PCB t; //定义一个空的结构体节点
int jcztsy = 0; //定义进程状态索引
bool ztgb = false; //在短进程当中是否有存在目标进程
函数说明:
void tjxx(int n) //打印统计信息
void xlxfw(int n) //先来先服务
void djcyx(int n) //短进程优先
int xxlr() //信息录入
void main() //主函数
程序运行结果图:
完整代码:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <windows.h>
//进程控制块(PCB)
struct PCB
{
char name;
float arrivetime;
float servetime;
float finishtime;
float roundtime;
float daiquantime;
};
struct PCB a[100];
struct PCB b[100];
char *jczt[] = { "运行", "就绪" };//*表示没有字符串的大小限制
//打印统计信息
void tjxx(int n)
{
float averoundtime = 0.0f; //定义平均周转时间
float avedaiquantime = 0.0f; //定义平均带权周转时间
printf("按任意键查看统计信息");
getchar(); getchar();
printf("\n\n进程名称\t到达时间\t服务时间\t完成时间\t周转时间\t带权周转时间");
for (int j = 0; j < n; j++)
{
printf("\n %c\t\t%4.f\t\t%4.f\t\t%4.f\t\t%4.f\t\t %.2f\n", a[j].name, a[j].arrivetime, a[j].servetime, a[j].finishtime, a[j].roundtime, a[j].daiquantime);
averoundtime += a[j].roundtime;
avedaiquantime += a[j].daiquantime;
}
printf("\n平均周转时间:%.2f", averoundtime / n);
printf("\n\n平均带权周转时间:%.2f\n", avedaiquantime / n);
}
//先来先服务
void xlxfw(int n)
{
int time = 0; //定义当前时刻
int jcnum = 0; //定义当前进程指向
struct PCB t; //定义一个空的结构体节点
int jcztsy = 0; //定义进程状态索引
while (1)
{
printf("当前时刻:%2d\n", time);
//排序
for (int i = 1; i < n; i++)
{
for (int j = 0; j < n - i; j++)
{
if (a[j].arrivetime > a[j + 1].arrivetime)
{
t = a[j];
a[j] = a[j + 1];
a[j + 1] = t;
}
if (a[j].arrivetime == a[j + 1].arrivetime)
{
if (a[j].servetime > a[j + 1].servetime)
{
t = a[j];
a[j] = a[j + 1];
a[j + 1] = t;
}
}
}
}
//遍历数组,注意同时达到的进程,所以采用for循环遍历
for (int k = 0; k< n; k++)
{
//是否有进程的到达时间等于当前时刻
if (time == a[k].arrivetime && a[k].arrivetime != 0)
{
//判断到达进程因该处于什么状态
if (k >= 1 && time >= a[k - 1].finishtime || k == 0)
{
jcztsy = 0;
}
else
{
jcztsy = 1;
}
printf("\t\t-------------------------------------------------------------------\n");
printf("\t\t进程 %c 到达\t进程状态\n", a[k].name);
printf("\n\t\t\t\t %s\n", jczt[jcztsy]);
printf("\t\t-------------------------------------------------------------------\n\n");
//必须这样写,0在下,1在上
if (jcnum >= 1)
{
a[k].finishtime = a[k - 1].finishtime + a[k].servetime;
a[k].roundtime = a[k].finishtime - a[k].arrivetime;
a[k].daiquantime = a[k].roundtime / a[k].servetime;
}
if (jcnum == 0)
{
a[k].finishtime = a[k].arrivetime + a[k].servetime;
a[k].roundtime = a[k].finishtime - a[k].arrivetime;
a[k].daiquantime = a[k].roundtime / a[k].servetime;
printf("\t\t-----------------------------\n");
printf("\t\t\t进程 %c 开始\n", a[jcnum].name);
printf("\t\t-----------------------------\n\n");
jcnum++;
}
}
//是否有进程的结束时间等于当前时刻
if (time == a[k].finishtime && a[k].finishtime != 0)
{
printf("\t\t-----------------------------\n");
printf("\t\t\t进程 %c 完成\n", a[k].name);
printf("\t\t-----------------------------\n\n");
}
//当前时刻是否满足大于等于下一进程达到时间,同时大于等于前一进程结束时间
if ((k >= 1 && time >= a[k].arrivetime && time == a[k - 1].finishtime && a[k].arrivetime != 0))
{
printf("\t\t-----------------------------\n");
printf("\t\t\t进程 %c 开始\n", a[k].name);
printf("\t\t-----------------------------\n\n");
}
}
//判断最后一个进程的结束没有,结束跳出循环
if (time > a[n - 1].finishtime && a[n - 1].finishtime != 0)
{
printf("\t\t-------------------------------------\n");
printf("\t\t\t现有进程已加载完毕! ^_^\n");
printf("\t\t-------------------------------------\n\n");
break;
}
time++;
Sleep(1000);
}
tjxx(n);
}
//短进程优先
void djcyx(int n)
{
struct PCB t;
int time = 0;//定义当前时刻
int jcnum = 0;
int jcztsy = 0;
bool ztgb = false;
//排序
for (int i = 1; i < n; i++)
{
for (int j = 0; j < n - i; j++)
{
if (a[j].arrivetime > a[j + 1].arrivetime)
{
t = a[j];
a[j] = a[j + 1];
a[j + 1] = t;
}
}
}
while (1)
{
printf("当前时刻:%d\n", time);
//遍历数组,注意同时达到的进程,所以采用for循环遍历
for (int k = 0; k< n; k++)
{
//是否有进程的到达时间等于当前时刻
if (time == a[k].arrivetime && a[k].arrivetime != 0)
{
//判断到达进程因该处于什么状态
if (k >= 1 && time >= a[k - 1].finishtime || k == 0)
{
jcztsy = 0;
}
else
{
jcztsy = 1;
}
printf("\t\t-------------------------------------------------------------------\n");
printf("\t\t进程 %c 到达\t进程状态\n", a[k].name);
printf("\n\t\t\t\t ----\n");
printf("\t\t-------------------------------------------------------------------\n\n");
}
}
if (jcnum == 0)
{
//遍历数组
for (int i = jcnum; i < n; i++)
{
//把当前到达的进程筛选出来
if (time >= a[i].arrivetime)
{
//从挑选出来的进程中选取服务时间最短的一个
if (a[i].servetime < a[jcnum].servetime)
{
t = a[jcnum];
a[jcnum] = a[i];
a[i] = t;
}
ztgb = true;
}
}
if (ztgb == true)
{
printf("\t\t-----------------------------\n");
printf("\t\t\t进程 %c 开始\n", a[jcnum].name);
printf("\t\t-----------------------------\n\n");
a[jcnum].finishtime = a[jcnum].arrivetime + a[jcnum].servetime;
a[jcnum].roundtime = a[jcnum].finishtime - a[jcnum].arrivetime;
a[jcnum].daiquantime = a[jcnum].roundtime / a[jcnum].servetime;
ztgb = false;
jcnum++;
}
}
if (time == a[jcnum - 1].finishtime && a[jcnum - 1].finishtime != 0)
{
printf("\t\t-----------------------------\n");
printf("\t\t\t进程 %c 完成\n", a[jcnum - 1].name);
printf("\t\t-----------------------------\n\n");
//遍历数组
for (int i = jcnum; i < n; i++)
{
//把当前到达的进程筛选出来
if (time >= a[i].arrivetime)
{
//从挑选出来的进程中选取服务时间最短的一个
if (a[i].servetime < a[jcnum].servetime)
{
t = a[jcnum];
a[jcnum] = a[i];
a[i] = t;
}
ztgb = true;
}
}
if (ztgb == true || jcnum == n - 1)
{
printf("\t\t-----------------------------\n");
printf("\t\t\t进程 %c 开始\n", a[jcnum].name);
printf("\t\t-----------------------------\n\n");
a[jcnum].finishtime = a[jcnum - 1].finishtime + a[jcnum].servetime;
a[jcnum].roundtime = a[jcnum].finishtime - a[jcnum].arrivetime;
a[jcnum].daiquantime = a[jcnum].roundtime / a[jcnum].servetime;
ztgb = false;
jcnum++;
}
}
if (time > a[n - 1].finishtime && a[n - 1].finishtime != 0)
{
printf("\t\t-------------------------------------\n");
printf("\t\t\t现有进程已加载完毕! ^_^\n");
printf("\t\t-------------------------------------\n\n");
break;
}
time++;
Sleep(1000);
}
tjxx(n);
}
//信息录入
int xxlr()
{
int n = 0;
srand(time(NULL)); //初始化随机函数
printf("\n\t\t请输入需要的进程数:");
scanf_s("%d", &n);
printf("\n");
for (int i = 0; i < n; i++)
{
printf("\t\t进程 %d\t名称:", i + 1);
scanf_s("%s", &a[i].name);
a[i].arrivetime = (float)(rand() % 5 + 1);
a[i].servetime = (float)(rand() % 5 + 1);
}
system("cls");
return n;
}
void main()
{
int b = 1, k;
while (b)
{
system("cls");
printf("\n\n\t\t进程调度算法\n\n");
printf("\t\t ----------------------------\n");
printf("\t\t|1.... 先来先服务算法 |\n");
printf("\t\t|2.... 短进程优先算法 |\n");
printf("\t\t|3.... 退出程序 |\n");
printf("\t\t ----------------------------\n");
printf("\t\t请选择:");
scanf_s("%d", &k);
switch (k)
{
case 1: xlxfw(xxlr()); break;
case 2: djcyx(xxlr()); break;
case 3: b = 0; break;
default:printf("\n\t\t请输入正确的选择!\n");
}
if (b != 0)
{
printf("\n"); system("pause");
}
}
printf("\n\t\t谢谢使用!\n\n\t\t");
}
如有错误,欢迎指正! _