操作系统实验二.docx
- 文档编号:28459048
- 上传时间:2023-07-13
- 格式:DOCX
- 页数:19
- 大小:213.76KB
操作系统实验二.docx
《操作系统实验二.docx》由会员分享,可在线阅读,更多相关《操作系统实验二.docx(19页珍藏版)》请在冰豆网上搜索。
操作系统实验二
操作系统实验
实验二进程管理
学号
1215108019姓名李克帆
学院信息学院
班级12电子
2
实验目的
1、理解进程的概念,明确进程和程序的区别。
2、理解并发执行的实质。
3、掌握进程的创建、睡眠、撤销等进程控制方法。
实验内容与要求
基本要求:
用C语言编写程序,模拟实现创建新的进程;查看运行进程;换出某个进程;杀死进程等功能。
实验报告内容
1、进程、进程控制块等的基本原理。
进程是现代操作系统中的一个最基本也是最重要的概念,掌握这个概念对于理解操作系统实质,分析、设计操作系统都有其非常重要的意义。
为了强调进程的并发性和动态性,可以给进程作如下定义:
进程是可并发执行的程序在一个数据集合上的运行过程,是系统进行资源分配和调度的一个独立单位。
进程又就绪、执行、阻塞三种基本状态,三者的变迁图如下:
I/完时间片
进程调
I/请
由于多个程序并发执行,各程序需要轮流使用CPU,当某程序不在CPU上运行时,必须保留其被中断的程序的现场,包括:
断点地址、程序状态字、通用寄存器的内容、堆栈内容、程序当前状态、程序的大小、运行时间等信息,以便程序再次获得CPU时,能够正确执行。
为了保存这些内容,需要建立—个专用数据结构,我们称这个数据结构为进程控制块PCB(ProcessControlBlock)。
进程控制块是进程存在的惟一标志,它跟踪程序执行的情况,表明了进程在当前时刻的状态以及与其它进程和资源的关系。
当创建一个进程时,实际上就是为其建立一个进程控制块。
在通常的操作系统中,PCB应包含如下一些信息:
①进程标识信息。
为了标识系统中的各个进程,每个进程必须有惟一的标识名或标识数。
②位置信息。
指出进程的程序和数据部分在内存或外存中的物理位置。
③状态信息。
指出进程当前所处的状态,作为进程调度、分配CPU的依据。
④进程的优先级。
一般根据进程的轻重缓急其它信息。
这里给出的只是一般操作系统中PCB所应具有的内容,不同操作系统的PCB结构是不同的,我们将在2.8节介绍Linux系统的PCB结构。
就
执行阻塞
程度为进程指定一个优先级,优先级用优先数表示。
⑤进程现场保护区。
当进程状态变化时(例如一个进程放弃使用CPU),它需要将当时的CPU现场保护到内存中,以便再次占用CPU时恢复正常运行,有的系统把要保护的CPU现场放在进程的工作区中,而PCB中仅给出CPU现场保护区起始地址。
⑥资源清单。
每个进程在运行时,除了需要内存外,还需要其它资源,如I/O设备、外存、数据区等。
这一部分指出资源需求、分配和控制信息。
⑦队列指针或链接字。
它用于将处于同一状态的进程链接成一个队列,在该单元中存放下一进程PCB首址。
⑧其它信息。
这里给出的只是一般操作系统中PCB所应具有的内容,不同操作系统的PCB结构是不同的,我们将在2.8节介绍Linux系统的PCB结构。
2、程序流程图。
开始
1
create创建新进程Run查看运行的进程5
Huanxing唤醒进程
功能选择(输入1~6)Huanchu换出进程4
Kill杀死进程
6
Viewall查看内存的状态7Exit(0)结束进程模拟程序
3、程序及注释。
#include
#include
structjincheng_type{//定义表示进程信息的结构体
intpid;
//进程ID
intyouxian;//优先级
intdaxiao;//大小
intzhuangtai;
//进程的状态,这里用0表示没有建立或被杀死,1表示执行,2表示换出
intinfo;
//内容
};
structjincheng_typeneicun[20];//定义20个内存单位给进程使用
intshumu=0,guaqi=0,pid,flag=0;//定义正在执行进程数目,被挂起进程数目,进程ID,运行标志位
voidcreate()//函数--创建一个新进程
{if(shumu>=20)printf(\n内存已满,请先换出或杀死进程\n);//判断内存空间是否已满
else{
for(inti=0;i<20;i++)
if(neicun[i].zhuangtai==0)break;//选出空着的内存单元给新进程使用
printf(\n请输入新进程pid\n);//输入新进程ID存至选出的内存单元
scanf(%d,&(neicun[i].pid));
for(intj=0;j
{printf(\n该进程已存在\n);return;
}
printf(\n请输入新进程优先级\n);//输入新进程的优先级、大小和内容
scanf(%d,&(neicun[i].youxian));printf(\n请输入新进程大小\n);scanf(%d,&(neicun[i].daxiao));printf(\n请输入新进程内容\n);scanf(%s,&(neicun[i].info));neicun[i].zhuangtai=1;//将新进程的内存单元状态(zhuangtai)设成1,以表示存在且未被换出
shumu++;
//正在运行的进程数目加一
}
}
voidrun()//函数--查看正在运行的进程
{for(inti=0;i<20;i++){if(neicun[i].zhuangtai==1)//将存在且未被挂起(即zhuangtai=1)的进程显示出来,若存在这样的程序,则将flag设成1
{printf(\npid=%d--,neicun[i].pid);printf(youxian=%d--,neicun[i].youxian);printf(daxiao=%d--,neicun[i].daxiao);printf(zhuangtai=%d--,neicun[i].zhuangtai);printf(info=%c,neicun[i].info);
flag=1;
}
}if(!
flag)
printf(\n当前没有运行进程\n);
//若当前没有运行进程(即flag=0),则显示当前没有运行进程
}
voidhuanchu()//函数--换出进程
{if(!
shumu)//判断是否无进程存在
{printf(\n当前没有进程存在\n);return;}
printf(\n输入唤出进程ID值);//输入需要换出的进程ID,
scanf(%d,&pid);for(inti=0;i<20;i++)
{if(pid==neicun[i].pid){if(neicun[i].zhuangtai==1)//若该ID代表的进程正在运行,则将其挂起,即将zhuangyai置成2,并将guaqi加一
{neicun[i].zhuangtai=2;
guaqi++;
printf(\n已经成功换出进程\n);
}
elseif(neicun[i].zhuangtai==2)printf(\n要唤出的进程已被挂起\n);
//若该ID代表的进程已被挂起,即zhuangtai==2,则显示'要唤出的进程已被挂起'
flag=1;break;
}
}
if(!
flag)printf(\n要唤出的进程不存在\n);//若进程不存在,给出显示
}
voidkill()//函数--杀死进程
{if(!
shumu)//判断是否无进程存在
{printf(\n当前没有进程存在\n);return;
}
printf(\n输入杀死进程的ID值);//读入要杀死的进程ID
scanf(%d,&pid);for(inti=0;i<20;i++){if(pid==neicun[i].pid)
{if(neicun[i].zhuangtai==1)//若进程正在运行则再次询问是否要杀死,通过用户的反馈执行不同操作
{printf(\n该进程正在运行,确定要杀死吗?
\n);printf(\n请输入1:
Yes;0:
NO\n);scanf(%d,&flag);if(flag)
{
neicun[i].zhuangtai=0;//将zhuangtai置为0,表示进程被杀死,并将shumu自减一
shumu--;
printf(\n已经成功杀死进程\n);}
elseprintf(\要杀死的进程正在运行\n);
}
elseif(neicun[i].zhuangtai==2)//若该进程已经被挂起,则直接杀死
{neicun[i].zhuangtai=0;shumu--;
printf(\n已经成功杀死进程\n);
}
flag=1;break;
}
}
if(flag==0)printf(\n要杀死的进程不存在\n);//若进程不存在,给出显示
}
voidhuanxing()//函数--唤醒进程
{if(!
shumu)//判断是否无进程存在
{printf(\n当前没有运行进程\n);return;
}
if(!
guaqi)//判断是否无进程被挂起
{printf(\n当前没有挂起进程\n);return;
}
printf(\n输入pid\n);//输入需要唤醒进程ID
scanf(%d,&pid);for(inti=0;i<20;i++){if(pid==neicun[i].pid)
{flag=false;
if(neicun[i].zhuangtai==2)//判断该进程是否被挂起,若没有则将其唤醒并将guaqi自减一
{neicun[i].zhuangtai=1;guaqi--;
printf(\n已经成功唤醒进程\n);
}
elseif(neicun[i].zhuangtai==2)printf(\n要唤醒的进程已被挂起\n);
//若目标进程已被挂起,则显示'要唤醒的进程已被挂起'
flag=1;break;
}
}if(!
flag)printf(\n要唤醒的进程不存在\n);//若要唤醒的进程不存在,给出显示
}
voidviewall()//函数--查看内存状态
{for(inti=0;i<20;i++)//显示所有20个内存单元的状态
{printf(\npid=%d,neicun[i].pid);printf(youxian=%d,neicun[i].youxian);printf(daxiao=%d,neicun[i].daxiao);printf(zhuangtai=%d,neicun[i].zhuangtai);printf(info=%c,neicun[i].info);
}
}
voidmain()//主函数
{intn=1;intnum;
for(inti=0;i<20;i++)//先将内存zhuangtai位清零
neicun[i].zhuangtai=0;
while(n)
{printf(\nfff\n);printf(\n*************************************************\n);
printf(\n1.创建新的进程\n);printf(\n2.查看运行进程\n);
printf(\n3.唤出某个进程\n);
printf(\n4.杀死某个进程\n);printf(\n5.唤醒某个进程\n);printf(\n
6.查看内存状态\n);
printf(\n7.退出进程\n);
printf(\n*************************************************\n);printf(\n请选择(1-7)\n);scanf(%d,&num);switch(num)//功能选择
{
case1:
create();break;case2:
run();break;case3:
huanchu();break;case4:
kill();break;case5:
huanxing();break;
case6:
viewall();break;case7:
exit(0);default:
n=0;}flag=0;
}
}
4、程序运行演示与截图
(1)创建新进程,依次建立进程1、2、3,图中为建立进程2。
(2)查看运行的进程与查看内存状态
(2)换出进程。
图中以换出进程3为例。
(4)此时再次查看运行的进程与查看内存状态,可以看到进程3已不在运行的进程中,内存状态中其zhuangtai标识等于2,表明进程3确实已被换出。
(5)唤醒进程。
图为将进程3唤醒。
(6)此时再次查看运行的进程与查看内存状态,可以看到进程3重新出现在运行的进程中,且内存状态中其zhuangtai标识等于1,表明进程3已被成功唤醒。
(7)杀死进程。
图中以杀死进程3为例,并附以杀死后运行的进程与内存状态
图,内存状态中进程3的zhuangtai=0,表示进程3已被杀死。
5、实验结论
通过这次实验,我了解到进程控制块在进程管理中的重要作用,它跟踪程序执行的情况,表明了进程在当前时刻的状态以及与其它进程和资源的关系。
同时也明白了我们平常使用程序的工作原理。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 操作系统 实验