本次实训的题目是操作系统整体设计,要求为设计一个小型的操作系统,主要包括打开文件(文件管理)、 为文件分配内存(存储管理, 选择任意的内存分配方法)和进程调度(处理机管理,选择任意的调度算法),至少3个进程。
实现操作系统,子任务:文件管理子系统,内存分配子系统,进程调度机制。
数据结构选择的链表进行模拟内存分配的顺序存储分配,最佳分配和最差分配;进程调度采用的队列形式存储进程,模拟进程调度的实现先来先服务(FCFS)、短作业优先(SJF)、高优先权优先(HPF)、高响应比优先(HRRF)、时间片轮转(RR)这五种算法。
界面长这样:
代码:
#include <stdio.h>
#include <stdlib.h>
#include<iostream>
#include<string.h>
#include<windows.h>
#include<bits/stdc++.h>
#define inf 0x3f3f3f
int N ; //总内存
using namespace std;
int color(int c);
struct node1 //链表是分区
{
int si, flag; //flag=0代表没用,flag=1代表已经占用
struct node1 *next, *pre;
char st[200], name[20];
};
struct node1 *tt;
int look_file(char st1[], struct node1 *head)//寻找文件名满足的内存
{
struct node1 *p;
p = head->next;
while(p)
{
if(p->flag == 1 && strcmp(p->name, st1) == 0)
{
//cout << p->st << endl;
tt = p;
return 1;
}
p = p->next;
}
return 0;
}
void see(struct node1 *head) //显示内存分配情况
{
struct node1 *p;
p = head->next;
color(5);
printf("内存分配情况:\n");
printf("\t文件名\t内存块大小\t是否使用\n");
color(15);
while(p)
{
if(p->flag == 0)
{
printf("\t空\t%d\t\t未使用\n",p->si);
}
else
{
printf("\t%s\t%d\t\t已使用\n",p->name, p->si);
}
p = p->next;
}
printf("\n\n");
}
int mode_1(int c, struct node1 *head, char n[]) //不排大小,按顺序分配
{
struct node1 *t, *t1;
t = head->next;
t1 = (struct node1*)malloc(sizeof(struct node1));
t1->next = NULL;
while(t)
{
if(t->si >= c && t->flag == 0)//内存
{
t->si = t->si - c;
t1->si = c;
t1->flag = 1;
t->flag = 0;
t->pre->next = t1;
t1->next = t;
t1->pre = t->pre;
t->pre = t1;
printf("分配内存成功!\n");
strcpy(t1->name, n);
printf("请输入文件内容:");
color(14);
cin >> t1->st;
color(15);
printf("新建文件成功!\n");
see(head); //看一下所有的内存块
return 1;
}
t = t->next;
}
return 0;
}
int mode_2(int c, struct node1 *head, char n[]) //最佳算法,从小到大排序
{
struct node1 *t, *t1, *t2;
t = head->next;
t2 = (struct node1*)malloc(sizeof(struct node1));
t2->next = NULL;
int ans = inf;
t2->flag = 1;
int k = 0;
while(t)
{
if(ans >= t->si && t->si >= c && t->flag==0)
{
ans = t->si;
t1 = t;
k = 1;
}
t = t->next;
}
if(k)
{
t2->si = c;
t1->si -= c;
t1->pre->next = t2;
t2->pre = t1->pre;
t1->pre = t2;
t2->next = t1;
strcpy(t2->name, n);
printf("分配内存成功!\n\n");
printf("请输入文件内容:");
color(14);
cin >> t2->st;
color(15);
printf("新建文件成功!\n");
see(head);
}
return k;
}
int mode_3(int c, struct node1 *head, char n[]) //最差算法
{
struct node1 *t, *t1, *t2;
t = head->next;
int k = 0;//分配成功标记
t2 = (struct node1*)malloc(sizeof(struct node1));
t2->next = NULL;
t2->si = c;
int maxx = t->si;
while(t)
{
if(t->si > maxx && t->flag == 0)
{
maxx = t->si;
t1 = t;
}
t = t->next;
}
if(maxx >= c)
{
t2->flag = 1;
t1->si -= c;
t1->pre->next = t2;
t2->pre = t1->pre;
t1->pre = t2;
t2->next = t1;
t1->flag = 0;
strcpy(t2->name, n);
printf("分配内存成功!\n");
k = 1;
printf("请输入文件内容:");
color(14);
cin >> t2->st;
color(15);
printf("新建文件成功!\n");
see(head);
}
return k;
}
void new_file(struct node1 *head)
{
printf("请输入要新建的文件名:");
char n[20];
color(14);
cin >> n;
color(15);
if(look_file(n, head))//新建文件是否已存在
{
color(12);
cout << "文件已存在!" << endl;
color(15);
return;
}
printf("请输入要分配的内存大小:");
int si;
color(14);
cin >> si;
color(15);
if(si > N)
{
printf("无足够的内存,分配失败!\n");
return;
}
printf("选择合适的分配算法:\n");
printf("1 首次适应算法 2 最佳适应算法 3 最坏适应算法\n");
int mode;
color(14);
cin >> mode;
color(15);
if(mode == 1)
{
if(!mode_1(si, head, n)) color(12), printf("内存不足,分配失败!\n"), color(15);;
}
else if(mode == 2)
{
if(!mode_2(si, head, n)) color(12),printf("内存不足,分配失败!\n"),color(15);;
}
else
{
if(!mode_3(si, head, n)) color(12), printf("内存不足,分配失败!\n"), color(15);;
}
return;
}
void show(struct node1 *head)//显示已有文件和所占内存
{
struct node1 *p;
p = head->next;
int k = 0;
printf("\t文件名\t所占内存\t内容\n");
while(p)
{
if(p->flag == 1)
{
printf("\t%s\t%d\t\t%s\n",p->name,p->si,p->st);
//cout << p->name <<\t<< p->si<<\t<< p->st << endl;
k = 1;
}
p = p->next;
}
if(!k)
{
printf("\t空\t空\t\t空\n");
color(12);
printf("还没有文件存在!\n");
color(15);
}
printf("\n");
}
void del(struct node1 *head)//删除与合并
{
printf("请输入要删除的文件名:");
char t[20];
color(14);
cin >> t;
color(15);
struct node1 *p;
p = head->next;
while(p)
{
if(strcmp(p->name, t) == 0)
{
if(p->next->flag == 0 && p->pre->flag == 0 && p->next!=NULL && p->pre!=head)
{
p->pre->si += p->si + p->next->si; //前后分区都空闲情况
if(p->next->next != NULL)
{
p->pre->next = p->next->next;
p->next->next->pre = p->pre;
p->pre->flag = 0;
}
else
{
p->pre->next = NULL;
}
}
else if((p->next->flag == 0 && p->pre->flag == 1&&p->next!=NULL&&p->pre!=head) || (p->next!=NULL&&p->next->flag==0&&p->pre==head))
{
p->si += p->next->si; //后面空闲前面不空闲
struct node1 *q;
q = p->next;
p->next = q->next;
if(q->next) q->next->pre = p;
p->flag = 0;
}
else if((p->next->flag == 1 && p->pre->flag == 0 &&p->pre!=head) || (p->pre!=head&&p->next==NULL&&p->pre->flag==0))
{
struct node1 *q;
q = p->pre;
q->si += p->si;
q->next = p->next;
p->next->pre = q;
q->flag = 0;
}
else p->flag = 0;
printf("删除成功!\n");
see(head);
return;
}
p = p->next;
}
color(12);
printf("不存在该文件!\n");
color(15);
return;
}
int color(int c)
{
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),c);
return 0;
}
typedef struct program
{
char name[20];
int running_time;
int enter_time;
int priority;
int done_time; //用于时间片轮转
int copyRunning_time; //用于时间片轮转
int start_time;
double response;
} Program;
void printf()
{
color(6);
printf("\t进程 到达时间 服务时间 开始时间 完成时间 周转时间 带权周转时间\n");
color(15);
}
void inputProgram(program pro[],int num)
{
for(int i=0; i<num; i++)
{
program prog ;
printf("请输入第%d个进程的名字,到达时间,服务时间\n",i+1);
scanf("%s",prog.name);
scanf("%d",&prog.enter_time) ;
scanf("%d",&prog.running_time);
prog.copyRunning_time = prog.running_time;
pro[i]=prog;
}
}
void sortWithEnterTime(program pro[],int num)
{
for(int i=1; i<num; i++)
{
for(int j= 0; j<num-i; j++)
{
if(pro[j].enter_time>pro[j+1].enter_time)
{
program temp = pro[j];
pro[j] = pro[j+1];
pro[j+1] = temp;
}
}
}
}
void FCFS(program pro[],int num)
{
printf();
sortWithEnterTime(pro,num); //按照进入顺序排序
queue<program> q;
q.push(pro[0]);
int time = pro[0].enter_time;
int pronum=1; //记录当前的进程
float sum_T_time = 0,sum_QT_time = 0 ;
while(q.size()>0)//监测队列中进程情况
{
program curpro = q.front();
q.pop();
if(time<curpro.enter_time)
time = curpro.enter_time;
int done_time = time+curpro.running_time;
int T_time = done_time - curpro.enter_time;//周转时间
sum_T_time += T_time;
float QT_time = T_time / (curpro.running_time+0.0) ;//带权周转时间
sum_QT_time += QT_time;
for(int tt = time; tt<=done_time&&pronum<num; tt++) //模拟进程的执行过程
{
if(tt==pro[pronum].enter_time)
{
q.push(pro[pronum]);
pronum++;
}
}
printf("\t%s\t%d\t%d\t%d\t%d\t%d\t%.2f\n",curpro.name,curpro.enter_time,curpro.running_time,time,done_time
,T_time,QT_time);
time += curpro.running_time;
if(q.size()==0&&pronum<num) //防止出现前一个进程执行完到下一个进程到达之间无进程进入
{
q.push(pro[pronum]);
pronum++;
}
}
printf("\t平均周转时间为%.2f\t平均带权周转时间为%.2f\n",sum_T_time/(num+0.0),sum_QT_time/(num+0.0));
}
void sortWithLongth(program pro[],int start,int end)
{
int len = end - start;
if(len == 1) return ;
for(int i=1; i<len; i++)
{
for(int j= start; j<end-i; j++)
{
if(pro[j].running_time>pro[j+1].running_time)
{
program temp = pro[j];
pro[j] = pro[j+1];
pro[j+1] = temp;
}
}
}
}
void SJF(program pro[],int num)
{
printf();
sortWithEnterTime(pro,num);
queue<program> q;
q.push(pro[0]);
int time = pro[0].enter_time;
int pronum=1; //记录当前的进程
float sum_T_time = 0,sum_QT_time = 0;
while(q.size()>0)
{
program curpro = q.front();
q.pop();
if(time<curpro.enter_time)
time = curpro.enter_time;
int done_time = time+curpro.running_time;
int T_time = done_time - curpro.enter_time;
float QT_time = T_time / (curpro.running_time+0.0) ;
sum_T_time += T_time;
sum_QT_time += QT_time;
int pre = pronum;
for(int tt = time; tt<=done_time&&pronum<num; tt++) //模拟进程的执行过程
{
if(tt==pro[pronum].enter_time) // 统计从此任务开始到结束之间有几个进程到达
{
pronum++;
}
}
sortWithLongth(pro,pre,pronum);//将到达的进程按照服务时间排序
for(int i=pre; i<pronum; i++) //将进程链入队列
{
q.push(pro[i]);
}
pre = pronum;
printf("\t%s\t%d\t%d\t%d\t%d\t%d\t%.2f\n",curpro.name,curpro.enter_time,curpro.running_time,time,done_time
,T_time,QT_time);
time += curpro.running_time;
if(q.size()==0&&pronum<num) //防止出现前一个进程执行完到下一个进程到达之间无进程进入
{
q.push(pro[pronum]);
pronum++;
}
//printf("size=%d\n",queue->size);
}
printf("\t平均周转时间为%.2f\t平均带权周转时间为%.2f\n",sum_T_time/(num+0.0),sum_QT_time/num);
}
void sortWithPriority(program pro[],int start,int end)
{
int len = end - start;
if(len == 1) return ;
for(int i=1; i<len; i++)
{
for(int j= start; j<end-i; j++)
{
if(pro[j].priority>pro[j+1].priority)
{
program temp = pro[j];
pro[j] = pro[j+1];
pro[j+1] = temp;
}
}
}
}
void HPF(program pro[],int num)
{
//printf();
sortWithEnterTime(pro,num);
queue<program> q;
q.push(pro[0]);
int time = pro[0].enter_time;
int pronum=1; //记录当前的进程
float sum_T_time = 0,sum_QT_time = 0;
for(int i=0; i<num; i++)
{
printf("请输入第%d进程的优先级:",i+1);
scanf("%d",&pro[i].priority);
}
printf();
while(q.size()>0)
{
program curpro = q.front();
q.pop();
if(time<curpro.enter_time)
time = curpro.enter_time;
int done_time = time+curpro.running_time;
int T_time = done_time - curpro.enter_time;
float QT_time = T_time / (curpro.running_time+0.0) ;
sum_T_time += T_time;
sum_QT_time += QT_time;
int pre = pronum;
for(int tt = time; tt<=done_time&&pronum<num; tt++) //模拟进程的执行过程
{
if(tt>=pro[pronum].enter_time) // 统计从此任务开始到结束之间有几个进程到达
{
pronum++;
}
}
sortWithPriority(pro,pre,pronum);//将到达的进程按照服务时间排序
for(int i=pre; i<pronum; i++) //将进程链入队列
{
q.push(pro[i]);
}
pre = pronum;
printf("\t%s\t%d\t%d\t%d\t%d\t%d\t%.2f\n",curpro.name,curpro.enter_time,curpro.running_time,time,done_time
,T_time,QT_time);
time += curpro.running_time;
if(q.size()==0&&pronum<num) //防止出现前一个进程执行完到下一个进程到达之间无进程进入
{
q.push(pro[pronum]);
pronum++;
}
}
printf("\t平均周转时间为%.2f\t平均带权周转时间为%.2f\n",sum_T_time/(num+0.0),sum_QT_time/(num+0.0));
}
void sortWithResponse(program pro[],int start,int end)
{
int len = end - start;
if(len == 1) return ;
for(int i=1; i<len; i++)
{
for(int j= start; j<end-i; j++)
{
if(pro[j].response<pro[j+1].response)
{
program temp = pro[j];
pro[j] = pro[j+1];
pro[j+1] = temp;
}
}
}
}
void HRRF(program pro[],int num) //高响应比优先
{
printf();
sortWithEnterTime(pro,num);
queue<program> q;
q.push(pro[0]);
int time = pro[0].enter_time;
int pre=1; //记录当前的进程
float sum_T_time = 0,sum_QT_time = 0;
while(q.size()>0)
{
program curpro = q.front();
q.pop();
if(time<curpro.enter_time)
time = curpro.enter_time;
int done_time = time+curpro.running_time;
int T_time = done_time - curpro.enter_time;
float QT_time = T_time / (curpro.running_time+0.0) ;
sum_T_time += T_time;
sum_QT_time += QT_time;
int pronum = pre;
for(int tt = time; tt<=done_time&&pronum<num; tt++) //模拟进程的执行过程
{
if(tt==pro[pronum].enter_time) // 统计从此任务开始到结束之间有几个进程到达
{
pro[pronum].response=(done_time-pro[pronum].enter_time)*1.0/pro[pronum].running_time;//计算响应比
pronum++;
}
}
sortWithResponse(pro,pre,pronum);//将到达的进程按照服务时间排序
q.push(pro[pre]);
pre +=1;
printf("\t%s\t%d\t%d\t%d\t%d\t%d\t%.2f\n",curpro.name,curpro.enter_time,curpro.running_time,time,done_time
,T_time,QT_time);
time += curpro.running_time;
if(q.size()==0&&pronum<num) //防止出现前一个进程执行完到下一个进程到达之间无进程进入
{
q.push(pro[pronum]);
pronum++;
}
if(pre>num) break;
}
printf("\t平均周转时间为%.2f\t平均带权周转时间为%.2f\n",sum_T_time/(num+0.0),sum_QT_time/num);
}
void PRR(program pro[],int num,int timeslice)
{
sortWithEnterTime(pro,num);
queue<program> q;
q.push(pro[0]);
pro[0].start_time = pro[0].enter_time;
int time = 0;
int pronum = 1;
printf("时间片进程轮转过程如下\n");
while(q.size()>0)
{
program curpro = q.front();
q.pop();
if(time<curpro.enter_time)
time = curpro.enter_time;
printf("%s\t",curpro.name);
_sleep(200);
if(timeslice >= curpro.running_time) // 如果剩余时间小于时间片 则此任务完成
{
for(int tt = time; tt<=time+curpro.running_time&&pronum<num; tt++) // 模拟进程的执行过程
{
if(tt==pro[pronum].enter_time) // 统计从此任务开始到结束之间有几个进程到达
{
pro[pronum].start_time = tt;
q.push(pro[pronum]);
pronum++;
}
}
time += curpro.running_time;
curpro.running_time = 0;
curpro.done_time = time;
if(q.size()==0&&pronum<num) //防止出现前一个进程执行完到下一个进程到达之间无进程进入
{
pro[pronum].start_time = pro[pronum].enter_time;
q.push(pro[pronum]);
pronum++;
}
continue;
}
for(int tt = time; tt<=time+timeslice&&pronum<num; tt++) //模拟进程的执行过程
{
if(tt==pro[pronum].enter_time) // 统计从此任务开始到结束之间有几个进程到达
{
pro[pronum].start_time = tt;
q.push(pro[pronum]);
pronum++;
}
}
time += timeslice;
curpro.running_time -= timeslice;
q.push(curpro); //当前程序未完成 继续添加到队列中
if(q.size()==0&&pronum<num) //防止出现前一个进程执行完到下一个进程到达之间无进程进入
{
pro[pronum].start_time = pro[pronum].enter_time;
q.push(pro[pronum]);
pronum++;
}
}
printf("轮转结束\n");
}
void RR(program pro[],int num)
{
printf("请输入时间片大小:");
int timeslice;
scanf("%d",×lice);
PRR(pro,num,timeslice);
printf();
sortWithEnterTime(pro,num);
queue<program> q;
q.push(pro[0]);
pro[0].start_time = pro[0].enter_time;
int time = 0;
int pronum = 1;
float sum_T_time = 0,sum_QT_time = 0;
while(q.size()>0)
{
program curpro = q.front();
q.pop();
if(time<curpro.enter_time)
time = curpro.enter_time;
if(timeslice >= curpro.running_time) // 如果剩余时间小于时间片 则此任务完成
{
for(int tt = time; tt<=time+curpro.running_time&&pronum<num; tt++) // 模拟进程的执行过程
{
if(tt==pro[pronum].enter_time) // 统计从此任务开始到结束之间有几个进程到达
{
pro[pronum].start_time = tt;
q.push(pro[pronum]);
pronum++;
}
}
time += curpro.running_time;
curpro.running_time = 0;
curpro.done_time = time;
int T_time = curpro.done_time-curpro.start_time;
float QT_time = T_time / (curpro.copyRunning_time+0.0);
sum_T_time += T_time;
sum_QT_time += QT_time;
printf("\t%s\t%d\t%d\t %d\t %d\t %d\t %.2f\n",curpro.name,curpro.enter_time,curpro.copyRunning_time,
curpro.start_time,curpro.done_time,T_time,QT_time);
if(q.size()==0&&pronum<num) //防止出现前一个进程执行完到下一个进程到达之间无进程进入
{
pro[pronum].start_time = pro[pronum].enter_time;
q.push(pro[pronum]);
pronum++;
}
continue;
}
for(int tt = time; tt<=time+timeslice&&pronum<num; tt++) //模拟进程的执行过程
{
if(tt>=pro[pronum].enter_time) // 统计从此任务开始到结束之间有几个进程到达
{
pro[pronum].start_time = tt;
q.push(pro[pronum]);
pronum++;
}
}
time += timeslice;
curpro.running_time -= timeslice;
q.push(curpro); //当前程序未完成 继续添加到队列中
if(q.size()==0&&pronum<num) //防止出现前一个进程执行完到下一个进程到达之间无进程进入
{
pro[pronum].start_time = pro[pronum].enter_time;
q.push(pro[pronum]);
pronum++;
}
}
printf("\t平均周转时间为%.2f\t平均带权周转时间为%.2f\n\n",sum_T_time/(num+0.0),sum_QT_time/(num+0.0));
}
void choiceMenu()
{
printf("\n\t请选择进程调度算法:\n");
color(11);
printf("-----------------------------------------------------\n");
printf("\t1.先来先服务算法\n\t2.短进程优先算法\n\t3.高优先级优先\n\t4.时间片轮转算法\n\t5.高响应比优先算法\n\t6.退出\n");
printf("-----------------------------------------------------\n");
color(15);
}
void Pmenu()
{
int proNum;
printf("请输入进程的个数:");
scanf("%d",&proNum);
program pro[proNum];
inputProgram(pro,proNum);
choiceMenu();
int choice;
while(1)
{
scanf("%d",&choice);
switch(choice)
{
case 1:
system("cls");
FCFS(pro,proNum);
choiceMenu();
break;
case 2:
system("cls");
SJF(pro,proNum);
choiceMenu();
break;
case 3:
system("cls");
HPF(pro,proNum);
choiceMenu();
break;
case 4:
system("cls");
RR(pro,proNum);
choiceMenu();
break;
case 5:
system("cls");
HRRF(pro,proNum);
choiceMenu();
break;
case 6:
printf("\n\n*******************退出进程管理子系统************************************************\n");
return;
}
}
}
void Mmenu()
{
printf("输入总内存容量 ");
scanf("%d",&N);
printf("\n");
struct node1 *head, *p;
head = new struct node1();
p = (struct node1*)malloc(sizeof(struct node1));
head->next = p;
head->pre = NULL;
p->si = N;
p->next = NULL;
p->pre = head;
p->flag = 0;
//int i;
int k;
while(1)
{
printf("\n");
printf("\t请选择要实现的功能:\n");
color(11);
printf("-------------------------------------------------------------------\n");
printf("\t1 显示已有文件\n\t2 打开文件\n\t3 新建文件并选择算法分配内存\n\t4 删除文件并回收内存\n\t5 退出程序\n");
printf("-------------------------------------------------------------------\n");
color(15);
color(14);
scanf("%d", &k);
color(15);
system("cls");
if(k == 1)
{
show(head);
}
else if(k == 2)
{
printf("请输入要打开的文件名:");
char look_name[20];
color(14);
cin >> look_name;
color(15);
int t = look_file(look_name, head);
color(12);
if(!t) cout << "文件不存在!" << endl;
else cout << tt->st << endl;
color(15);
}
else if(k == 3)
{
new_file(head);
}
else if(k == 4)
{
del(head);
}
else
{
printf("\n\n*******************退出内存管理子系统**********************************************\n");
return;
}
}
}
int main()
{
int k;
printf("********************欢迎来到小型操作系统模拟**********************************\n");
while(1)
{
printf("\n");
printf("\t请选择要实现的功能:\n");
color(11);
printf("-------------------------------------------------------------------\n");
printf("\t1 存储器管理(内存分配算法)\n\t2 处理器管理(进程调度算法)\n\t3 退出程序\n");
printf("-------------------------------------------------------------------\n");
color(15);
color(14);
scanf("%d", &k);
color(15);
system("cls");
if(k == 1)
{
Mmenu();
}
else if(k == 2)
{
Pmenu();
}
else
{
printf("系统运行结束!\n");
break;
}
}
return 0;
}