操作系统实验报告1.docx
- 文档编号:25190773
- 上传时间:2023-06-06
- 格式:DOCX
- 页数:13
- 大小:198.78KB
操作系统实验报告1.docx
《操作系统实验报告1.docx》由会员分享,可在线阅读,更多相关《操作系统实验报告1.docx(13页珍藏版)》请在冰豆网上搜索。
操作系统实验报告1
实验报告
实验名称:
进程管理
课程名称:
操作系统B
班级:
计G191
姓名:
刘祎
学号:
2019322057
教师:
唐静
信息工程学院计算机系
实验名称
进程管理
成绩评定
(,,)
评分标准
总分15分,分布在以下两个指标点:
1.2工程知识:
5分,综合考察解题思路、代码准确性等方面的能力和水平
4.3研究:
5分,综合考察态度、报告完整性、实验总结等方面的能力和水平
5.1工具使用:
5分,考察代码执行、调试过程、结果分析等方面的能力和水平
实验目的
#参照实验指导书,填写实验目的与要求
1.加深对进程概念的理解,明确进程和程序的区别。
2.进一步认识并发执行的实质。
3.分析进程争用资源的现象,学习解决进程互斥的方法。
4.了解Linux系统中进程通信的基本原理。
实
验
内
容
1.进程的创建
编写一段程序,使用系统调用fork()创建两个子进程。
当此程序运行时,在系统中有一个父进程和两个子进程活动。
让每一个进程在屏幕上显示一个字符:
父进程显示字符“a”;子进程分别显示字符“b”和“c”。
试观察记录屏幕上的显示结果,并分析原因。
2.进程的控制
修改已编写的程序,将每个进程输出一个字符改为每个进程输出一句话,再观察程序执行时屏幕上出现的现象,并分析原因。
如果在程序中使用系统调用lockf()来给每个进程加锁,可以实现进程间互斥,观察并分析出现的现象。
3.进程的软中断通信
(1)编制一段程序,使其实现进程的软中断通信。
要求:
使用系统调用fork()创建两个子进程,再用系统调用signal()让父进程捕捉键盘上来的中断信号(按del键);当捕捉到中断信息之后,父进程用系统调用kill()向两个子进程发出信号,子进程捕捉到信号后分别输出下列信息后终止:
childprocess1iskilledbyparent!
childprocess2iskilledbyparent!
父进程等到两个子进程终止后,输出如下的信息后终止:
Parentprocessiskilled!
(2)在上面的程序中增加语句signal(SIGHT,SIG_IGN)和signal(SIGQUIT,SIG_IGN),观察执行结果,并分析原因。
实
验
环
境
操作系统环境:
Linux
编程语言:
C语言
软件:
VM,CRT
编译器:
vim
实
验
说
明
1.解题思路:
进程的创建:
p1进程fork之后,p1变为父进程,生成一个p1的子进程,父进程的p1返回的不是0,输出b,p1的子进程p儿子1由于是返回的0所以进入else判断区域,此时遇到了p2进程,同样上面操作,在p儿子1手下{p2作为了父亲输出了c,p2儿子输出了a}但是是由于两个进程就是独立个体,各自运行,互不干扰,父子进程谁先执行不由fork决定,而是由系统当前环境和进程调度算法决定,因此根据个人系统情况不同,打出上述所有的顺序都不一定。
进程的控制:
lockf(1,1,0)是锁定屏幕输出,不让其他进程可以输出到屏幕,lockf(1,0,0)则是解锁,使得每一个for循环都能完整执行并输出,但是三个输出的顺序依然不定。
进程的软中断通信:
SIGINT信号:
程序终止(interrupt)信号,在用户键入INTR字符(通常是Ctrl-C)时发出,用于通知前台进程组终止进程。
接收默认处理:
接收默认处理的进程通常会导致进程本身消亡。
例如连接到终端的进程,用户按下CTRL+c,将导致内核向进程发送一个SIGINT的信号,进程如果不对该信号做特殊的处理,系统将采用默认的方式处理该信号,即终止进程的执行。
实
验
说
明
实验1
#include
main()
{
intp1,p2;
while((p1=fork())==-1);
if(p1==0)
putchar('b');
else
{
while((p2=fork())==-1);
if(p2==0)
putchar('c');
else
putchar('a');
}
}
实验2
#include
#include
main()
{
intp1,p2,i;
while((p1=fork())==-1);
if(p1==0)
{
lockf(1,1,0);
for(i=0;i<50;i++)
printf("child%d\n",i);
lockf(1,0,0);
}
else{
while((p2=fork())==-1);
if(p2==0)
{
lockf(1,1,0);
for(i=0;i<50;i++)
printf("son%d\n",i);
lockf(1,0,0);
}
else{
lockf(1,1,0);
for(i=0;i<50;i++)
printf("daughter%d\n",i);
lockf(1,0,0);}
}
}
实验3
(1)
#include
#include
#include
#include
#include
voidwaiting(),stop(),alarming();
intwait_mark;
intmain()
{
intp1,p2;
if(p1=fork())/*创建子进程p1*/
{//子进程1创建成功,当前运行的是子进程1的父进程
if(p2=fork())/*创建子进程p2*/
{//子进程2创建成功,当前运行的是子进程2的父进程
wait_mark=1;
signal(SIGINT,stop);//不到5s就捕获CTRL+C信号,执行stop操作
signal(SIGALRM,alarming);//接收到SIGALRM信号,执行alarming操作
waiting();//如果捕捉到此时wait_mark=0不等待
kill(p1,16);//向p1进程发16中断发生的信号
wait(0);//阻塞父进程等待中断16发生后终止子进程1
kill(p2,17);//向p1进程发17中断发生的信号
wait(0);//阻塞父进程等待中断17发生后终止子进程2
printf("parentprocessiskilled!
\n");
exit(0);//终止父进程
}
else
{//当前是在子进程2创建成功的条件下运行的是子进程的2的子进程
wait_mark=1;
signal(17,stop);
signal(SIGINT,SIG_IGN);
while(wait_mark!
=0);
lockf(1,1,0);
printf("childprocess2iskilledbyparent!
\n");
lockf(1,0,0);
exit(0);
}
}
else
{//当前是在子进程1创建成功的条件下运行的是子进程1的子进程
wait_mark=1;
signal(16,stop);//接收到中断16发生的信号,置wait_mark为0
signal(SIGINT,SIG_IGN);//CTRL+C信号发生时,都会接收到信号,会把子进程给结束,所以要屏蔽掉。
while(wait_mark!
=0);//wait_mark不为0会锁死在这,这就是5s内都不干程序也什么都不干的原因
lockf(1,1,0);
printf("childprocess1iskilledbyparent!
\n");
lockf(1,0,0);
exit(0);
}
}
voidwaiting()
{
sleep(5);//5s后唤醒
if(wait_mark!
=0)
kill(getpid(),SIGALRM);//如果5s之后检测wait_mark不是0,发出SIGALRM信号
}
voidalarming()
{
wait_mark=0;
}
voidstop()
{
wait_mark=0;
}
实验3
(2)
#include
#include
#include
intpid1,pid2;
intEndFlag=0,pf1=0,pf2=0;
voidIntDelete(){
kill(pid1,16);
kill(pid2,17);
EndFlag=1;
}
voidInt1()
{
printf("childprocess1iskilledbyparent!
");
exit(0);
}
voidInt2()
{
printf("childprocess2iskilledbyparent!
");
exit(0);
}
main(){
intexitpid;
signal(SIGINT,SIG_IGN);
signal(SIGQUIT,SIG_IGN);
while((pid1=fork())==-1);
if(pid1==0)
{
printf("p1\n");
signal(SIGUSR1,Int1);
signal(16,SIG_IGN);
pause();
exit(0);
}
else
{
while((pid2=fork())==-1);
if(pid2==0){
printf("p2\n");
signal(SIGUSR2,Int2);
signal(17,SIG_IGN);
pause();
exit(0);
}
else
{
printf("parent\n");
signal(SIGINT,IntDelete);
waitpid(-1,&exitpid,0);
printf("parentprocessiskilled!
\n");
exit(0);
}
}
}
实
验
说
明
从进程并发执行来看,输出bac、acb等情况都有可能。
fork()创建进程所需的时间要多于输出一个字符的时间,因此在主进程创建进程2的同时,进程1就输出了“b”,而进程2和主程序的输出次序是有随机性的,所以会出现上述结果。
由于函数printf()输出的字符串中间不会被中断,因此,字符串内部的字符顺序输出时不变,但是,由于进程并发执行时的调度顺序和父子进程的抢占处理机问题,输出字符串的顺序随着执行的不同而发生变化,这与打印单字符的结果类似。
因为上述程序执行时,不同进程之间不存在共享临界资源(其中打印机的互斥性已由操作系统保证)问题,所以,加锁与不加锁效果相同。
实
验
说
明
上述程序中,使用系统调用signal()都放在一段程序的前面部分,而不是在其他接收信号处。
这是因为signal()的执行只是为进程指定信号量16或17的作用,以及分配相应的与stop()过程链接的指针。
从而,signal()函数必须在程序前面部分执行。
由于忽略了终端与退出信号,程序会一直保持阻塞状态而无法退出。
分
析
与
思
考
此次实验让我知道如何安装虚拟机,安装Linux操作系统。
通过crt连接虚拟机。
在实验过程中逐渐了解进程的概念,也知道了如何调用fork创建子进程,通过lockf进行加锁操作。
对c语言的了解也增加了一些,通过同学的帮助,上网搜索资料。
渐渐懂得了一些基本操作,熟知了vim的使用方法。
如何正确安装gcc编译器。
对知识理解更加透彻。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 操作系统 实验 报告
![提示](https://static.bdocx.com/images/bang_tan.gif)