操作系统原理
题
目:模拟进程创建、终止、阻塞、唤醒原语 院 (部):
管理工程学院 专
业:
信息管理与信息系统 班
级:
信管 姓
名:
学
号:
实验题目一:模拟进程创建、终止、阻塞、唤醒原语 一、题目类型:必做题目。
二、实验目的:通过设计并调试创建、终止、阻塞、唤醒原语功能,有助于对操作系统中进程控制功能的理解,掌握操作系统模块的设计方法和工作原理。
三、实验环境:
1、硬件:pc机及其兼容机。
2、软件:Windows OS,Turbo C或C++、VC++、VS.net、Java等。
四、实验内容:
1、设计创建、终止、阻塞、唤醒原语功能函数。
2、设计主函数,采用菜单结构(参见后面给出的流程图)。
3、设计“显示队列”函数,目的能将就绪、阻塞队列中的进程信息显示在屏幕上,以供随时查看各队列中进程的变化情况。
五、算法流程图
开始
系统主菜单 1…创建 2…阻塞 3…唤醒 4…终止 5…显示 0…退出 请输入您需要的功能(0-5):
输入选择=?
5 4 3 2 1 0
退出 创建 阻塞 唤醒 终止 显示
结束
六、程序清单 #include <stdio.h> #include <string.h> struct pcb {
char name[10];
int status;
int order;
int time;
int wtime;
int ytime; }pcb[11];//该结构体用于存储已经输入的进程 struct ghost {
char name[10];
int status;
int order;
int time; }ghost[11];//该结构体用于优先级调度时,进程的优先级排序 char a_name[10]; int i=0,y,a=0,x,z,jilu; void insert(); void block(); void rouse(); void stop(); void outPut(); void control();//实验二添加函数 void order_control();//实验二添加函数 void time_control();//实验二添加函数 void insert() {
jilu=0;//jilu是一个用于判断的变量,在重复时进行判断跳过
if(i>=10)
printf(“进程已经存在10个,无法继续添加进程\n“);
else
{
printf(“请输入插入pcb的数据:\n“);
printf(“1、进程名:“);
scanf(“%s“,&pcb[i].name);
printf(“2、该进程的优先级(1-10):“);
scanf(“%d“,&pcb[i].order);
printf(“3、运行时间“);
scanf(“%d“,&pcb[i].time);
for(y=0;y<i;y++)
{
if (strcmp(pcb[i].name,pcb[y].name)==0)
{
printf(“您输入的进程名已经存在,请重新输入!\n“);
jilu=y+1;
}
}
if(jilu>0)jilu=0;
else
{
printf(“输入已经完成\n您输入的数据为:\n进程名:
%s\n优先级:
%d\n运行时间:
%d\n“,pcb[i].name,pcb[i].order,pcb[i].time);
printf(“------------------------------------------------------------------\n“);
strcpy(ghost[i].name,pcb[i].name);
ghost[i].order=pcb[i].order;
ghost[i].time=pcb[i].time;
pcb[i].status=1;
ghost[i].status=1;
pcb[i].wtime=pcb[i].time;
pcb[i].ytime=0;
i++;
}
} } void block() {
int m;
printf(“\n请输入您要改变状态的进程的进程名:
“);
scanf(“%s“,&a_name);
for(y=0;y<=i;y++)
{
if(strcmp(pcb[y].name,a_name)==0)
{
a=1;
if(pcb[y].status==0)
{
printf(“您要修改的进程已经是阻塞状态,无法更改\n“);
}
if(pcb[y].status==2)
{
pcb[y].status=0;
for(m=0;m<=i;m++)
{
if(strcmp(ghost[m].name,a_name)==0)
{
ghost[m].status=0;
}
}
printf(“操作已完成,进程成功改为阻塞状态\n“);
}
}
}
if(a==0)
{
printf(“对不起!您查找的进程名不存在\n“);
}
a=0; } void rouse() {
int m;
printf(“\n请输入您要改变状态的进程的进程名:
“);
scanf(“%s“,&a_name);
for(y=0;y<=i;y++)
{
if(strcmp(pcb[y].name,a_name)==0)
{
a=1;
if(pcb[y].status==1)
{
printf(“您要修改的进程已经是就绪状态,无法更改\n“);
break;
};
if(pcb[y].status==0)
{
pcb[y].status=1;
for(m=0;m<=i;m++)
{
if(strcmp(ghost[m].name,a_name)==0)
{
ghost[m].status=1;
}
}
printf(“操作已完成,进程成功改为运行状态\n“);
break;
}
}
}
if(a==0)
{
printf(“对不起!您查找的进程名不存在\n“);
}
a=0; } void stop() {
printf(“\n请输入您要改变状态的进程的进程名:
“);
scanf(“%s“,&a_name);
for(y=0;y<=i;y++)
{
if(strcmp(pcb[y].name,a_name)==0)
{
a=1;
for(;y<i;y++)
{
pcb[y]=pcb[y+1];
}
i--;
printf(“操作已完成,进程成功删除\n“);
break;
}
}
if(a==0)
{
printf(“对不起!您查找的进程名不存在\n“);
}
a=0; } void outPut() {
if(i==0)
{
printf(“对不起,没有进程存在,无法显示\n“);
}
else
{
printf(“\n\n
已存在进程分别为:(状态:2表示正在运行,1表示就绪,0表示阻塞)\n“);
for(y=0;y<i;y++)
{
if(pcb[y].status!=3)printf(“进程%d
进程名:
%s
状态: %d\n“,y+1,pcb[y].name,pcb[y].status);
}
} } void control() {
for(;1;)
{
printf(“进程调度子菜单\n0
:返回主菜单\n1
:优先级调度\n2
:时间片轮转调度\n请输入您想要进行的操作的指令 : “);
scanf(“%d“,&x);
if(x==0)
break;
switch(x)
{
case 0:
break;
case 1:
order_control();
break;
case 2:
time_control();
break;
default:
printf(“您输入的指令有误,请重新输入\n“);
break;
}
} } void order_control() {
int jishi;//用于CPU运行时间计时
jishi=0;
char panduan1,panduan2;//用于判断是否继续调度
struct ghost jiaohuan;
int gg,bl;
for(gg=0;gg<i;gg++)
{
if(pcb[gg].status==2)
{
for(bl=0;bl<i;bl++)
{
if(strcmp(ghost[bl].name,pcb[gg].name)==0)
{
ghost[bl].status=2;
}
}
}
}
for(x=0;x<i-1;x++)
{
for(y=x+1;y<i;y++)
{
if(ghost[x].order<ghost[y].order)
{
jiaohuan=ghost[x];
ghost[x]=ghost[y];
ghost[y]=jiaohuan;
}
}
}//以上语句是根据优先级为进程排序
printf(“\n\n按照优先级调度进程,具体内容为:\n“);
for(x=0;x<i;x++)
{
if(ghost[x].status==1){
printf(“正在运行的进程:
%s\n优先级:
%d\n运行时间:
%d\n\n\n“,ghost[x].name,ghost[x].order,ghost[x].time);
for(y=0;y<=i;y++)
{
if(strcmp(pcb[y].name,ghost[x].name)==0)
{
pcb[y].status=2;
ghost[x].status=2;
}
};//该语句用于更改另一个结构体进程的状态
printf(“是否继续运行直至进程运行完毕(Y/N)“);
scanf(“%s“,&panduan1);
if(panduan1=='Y'||panduan1=='y')
{
if(ghost[x].status==2)
{
jishi=jishi+ghost[x].time;
printf(“CPU运行时间 %d ,进程 %s 运行完毕,正在关闭!\n“,jishi,ghost[x].name);
for(y=0;y<=i;y++)
{
if(strcmp(pcb[y].name,ghost[x].name)==0)
{
pcb[y].status=3;
ghost[x].status=3;
}
};//该语句用于更改另一个结构体进程的状态
if(x==(i-1))
{
printf(“所有进程全部运行完毕!\n-------------------------------------------------------\n“);
}
else{
printf(“--------------------------------------------------------------\n是否继续调度(y/n)“);
scanf(“%s“,&panduan2);
if(panduan2=='N'||panduan2=='n')break;}
}}else break;
}
}printf(“如果无输出内容,请检查就绪队列是否存在进程“); } void time_control() {
int z,kz1,kz2,kz3,kz4,kz5,kz6;//kz1表示时间片运行的时间计时,kz2表示CPU运行的总时间,kz3用于所有进程时间的输出kz4表示已完成的进程数kz5用于表示状态为就绪的进程的个数kz6用于更改ghost的状态值
z=0;kz2=0;kz4=0;kz5=0;
for(y=0;y<i;y++)
{
if(pcb[y].status==1)
{
kz5=kz5+1;
}
}
printf(“\n\n请输入时间片长度: “);
scanf(“%d“,&x);
printf(“\n\n按照时间片轮转调度进程,具体内容为:\n“);
if(kz5!=0)
{
for(;kz4<kz5;)
{
for(y=0;y<i;y++)
{
if(pcb[y].status==1||pcb[y].status==2)
{
for(kz1=0;kz1<x;kz1++)
{
if(pcb[y].status==1||pcb[y].status==2){
kz2=kz2+1;
pcb[y].wtime=pcb[y].wtime-1;
pcb[y].ytime=pcb[y].ytime+1;
printf(“CPU运行时间: %d ,正在运行进程: %s\n“,kz2,pcb[y].name);
printf(“进程名
已运行时间
未运行时间
要求运行时间\n“);
for(kz3=0;kz3<i;kz3++)
{
if(pcb[kz3].status==1||pcb[kz3].status==2)
{
printf(“%s%12d%12d%12d\n“,pcb[kz3].name,pcb[kz3].ytime,pcb[kz3].wtime,pcb[kz3].time);
}
}
if(pcb[y].wtime<=0&&pcb[y].status!=3)
{
printf(“进程 %s 运行完毕,正在关闭!\n-------------------------------------------------------------------\n“,pcb[y].name);
kz4=kz4+1;
pcb[y].status=3;
for(kz6=0;kz6<i;kz6++)
{
if(strcmp(ghost[kz6].name,pcb[y].name)==0)
{
ghost[kz6].status=3;
}
}
kz1=x;
break;
}
printf(“-------------------------------------------------------------------\n“);
}}
}
}
}
}
printf(“注意:如果未输出过程,请检查就绪列表是否存在进程\n“); } void main() {
char c;
for(;1;)
{
printf(“系统主菜单\n“);
printf(“1、创建\n“);
printf(“2、阻塞\n“);
printf(“3、唤醒\n“);
printf(“4、终止\n “);
printf(“5、显示\n“);
printf(“6、调度\n“);
printf(“0、退出\n“);
printf(“请输入操作指令 :
“);
if(scanf(“%d“,&x))
{
if(x==0)
break;
switch(x)
{
case 1:
insert();
break;
case 2:
block();
break;
case 3:
rouse();
break;
case 4:
stop();
break;
case 5:
outPut();
break;
case 6:
control();
break;
case 0:
break;
default:
printf(“格式非法,请重新输入\n“);
break;
}
}
else if(scanf(“%c“,&c))
{
printf(“格式非法,请重新输入\n“);
}
} } 七、程序中使用的数据结构及符号说明 struct pcb {
char name[10];
int status;
int order;
int time;
int wtime;
int ytime; }pcb[11];//该结构体用于存储已经输入的进程 struct ghost {
char name[10];
int status;
int order;
int time; }ghost[11];//该结构体用于优先级调度时,进程的优先级排序 void insert();//添加进程 void block();//阻塞进程 void rouse();//唤醒进程 void stop();//删除进程 void outPut();//输出 void control();//实验二添加函数 void order_control();//实验二添加函数 void time_control();//实验二添加函数 八、调试程序时出现问题及解决方法 问题一:
现象:使用阻塞功能后,输出功能无法正常显示进程状态。
解决:在进程的结构体中添加控制进程状态的变量。