操作系统 第三次第四次实验.docx
《操作系统 第三次第四次实验.docx》由会员分享,可在线阅读,更多相关《操作系统 第三次第四次实验.docx(13页珍藏版)》请在冰豆网上搜索。
操作系统第三次第四次实验
操作系统课程实验报告
姓名
XX
学号
1001010127
系
计算机
任课教师
XX
指导教师
XX
评阅教师
贺辉
实验地点
综合楼B102
实验时间
2012/10/24
实验课表现
出勤和个人表现Q1(15+15(组长评分)=30分)
得分:
实验
总分
(Q1+Q2+Q3)
实验完成情况Q2(60分)
得分:
体会
实验过程中遇到的问题解决办法与实验体会Q3(10分)
得分:
实验编号与实验名称:
实验目的:
1 管理Linux系统进程
1)回顾系统进程的概念,加深对Linux/UNIX进程管理的理解。
2)回顾ps命令和选项。
3)列出当前shell中的进程。
4)列出运行在系统中的所有进程。
2 进程互斥实验
1、进一步认识并发执行的实质
2、通过分析实验结果,分析进程竞争资源的现象,学习解决进程互斥的方法
3 进程的控制实验
1、掌握进程另外的创建方法:
需认真分析实验结果,体会本次实验进程创建方法与fork的不同
2、通过分析实验结果,熟悉进程的睡眠、同步、撤消等进程控制方法
实验内容
1、用fork()创建一个进程,再调用exec()用新的程序替换该子进程的内容
2、利用wait()来控制进程执行顺序
实验内容及要求(详见实验讲义与实验指导书):
实验用到的软件(:
)
实验内容及关键步骤(代码)Q2(60分)
步骤1:
登录进入Linux。
步骤2:
访问命令行。
单击“系统工具”-“终端”命令,打开“终端”窗口。
步骤3:
回顾系统进程概念。
每个运行的程序都会创建一个进程,进程分配到一个唯一的进程标识符(PID)。
PID被系统用于标识和跟踪进程,直到进程结束。
1)Linux系统中,几乎每一个启动的进程,都会由内核分配一个唯一的______PID_________,用于跟踪从进程启动到进程结束。
2)当启动新进程的时候,内核也给它们分配系统资源,如__CPU______和____RAM____。
3)永远不向父进程返回输出的进程叫做___僵进程___________。
4)由父进程派生出来的进程叫做___________子_______进程。
5)________父________进程是一个派生另一个进程的进程。
6)运行用于提供服务的Linux系统进程是__sched(调度)和init(初始化)_____________。
7)如果父进程在子进程之前结束,它创建了一个______孤儿________进程。
步骤5:
列出系统中运行的所有进程。
输入ps-ef命令,显示运行在系统中的各个进程的完全信息。
执行该命令,并与ps–f命令的输出结果对照,一致吗?
有何不同?
不一致:
Ps–ef:
Ps–f:
Psef表示的是所有进程的完整列表,而ps–f表示的是一个进程的完整列表。
在范围上不一样。
注意分析当前终端窗口中的输出结果:
a.显示了多少个进程?
___________________144________________________________________________
b.PID是什么?
进程的进程标识号。
PID可以用来杀死进程______________________________________________________________
c.启动进程的命令(CMD)是什么?
命令名守护进程执行的程序的名字_____________________________________________
d.请观察,什么命令的PID号是1?
__________sbin/init__________________________________________________
e.再次运行 ps-ef|wc-l命令,计算进程的数目并把输出结果输入到wc命令中:
____________144________________________________________________________
执行manps命令,可以打开Linux用户命令手册,了解ps命令的用法,输入wq命令可退出用户手册的阅读。
man命令可以执行吗?
结果如何?
可执行
______________________________________________________________
试调试下二段代码。
并写明结果(考虑fork与sleep是什么函数)
1.intmain()
{
intp1,i;
while((p1=fork())==-1);
if(p1>0)
for(i=0;i<5;i++)
{
printf("Iamparent.\n");
sleep
(1);
}
else
for(i=0;i<5;i++)
{
printf("Iamchild.\n");
sleep
(1);
}
return0;
}
结果:
2、
intmain()
{
intp1,i;
while((p1=fork())==-1);
if(p1>0)
{
wait(0);
for(i=0;i<5;i++)
{
printf("Iamparent.\n");
sleep
(1);
}
}
else
{
for(i=0;i<5;i++)
{
printf("Iamchild.\n");
sleep
(1);
}
exit(0);
}
return0;
}
结果:
父子进程到底谁先得到调度执行是由操作系统在运行时决定的,而且系统中也不止这两个进程,所以即使你使用了sleep让它睡眠,谁先运行谁后运行也是不确定的。
而且每次运行的结果也不一样
Fork()函数:
一个现有进程可以调用fork函数创建一个新进程。
由fork创建的新进程被称为子进程(childprocess)。
fork函数被调用一次但返回两次
Sleep()函数:
执行挂起一段时间,就是在执行的过程中,让执行停顿一下!
2 进程互斥实验
1.修改以下代码,用lockf()来给每一个进程加锁,以实现进程之间的互斥
//=======================================
#include
main()
{
intp1,p2;
while((p1=fork())==-1); /*创建子进程p1*/
if(p1==0) putchar('b');
else
{
while((p2=fork())==-1); /*创建子进程p2*/
if(p2==0) putchar('c');
else putchar('a');
}
}
答案:
循环十次:
答案:
很容易看出答案不一样了,bc的顺序倒过来了!
没有加锁的答案:
2、
#include
main()
{
intp1,p2,i;
while((p1=fork())==-1); /*创建子进程p1*/
if(p1==0)
for(i=0;i<10;i++)
printf("daughter %d\n",i);
else
{
while((p2=fork())==-1); /*创建子进程p2*/
if(p2==0)
for(i=0;i<10;i++)
printf("son %d\n",i);
else
for(i=0;i<10;i++)
printf("parent %d\n",i);
}
}
答案:
这个程序和上面的程序是一样原理的,没有什么可比性,我就不执行这个程序了!
循环输出也在上面的程序执行了!
(四)分析以下程序的输出结果【写进实验报告】:
#include
#include
main()
{
intp1,p2,i;
int*fp;
fp=fopen("to_be_locked.txt"
,"w+");
if(fp==NULL)
{
printf("Failtocreatefile");
exit(-1);
}
while((p1=fork())==-1); /*创建子进程p1*/
if(p1==0)
{
lockf(*fp,1,0); /*加锁*/
for(i=0;i<10;i++)
fprintf(fp,"daughter%d\n",i);
lockf(*fp,0,0); /*解锁*/
}
else
{
while((p2=fork())==-1); /*创建子进程p2*/
if(p2==0)
{
lockf(*fp,1,0); /*加锁*/
for(i=0;i<10;i++)
fprintf(fp,"son%d\n",i);
lockf(*fp,0,0); /*解锁*/
}
else
{
wait(NULL);
lockf(*fp,1,0); /*加锁*/
for(i=0;i<10;i++)
fprintf(fp,"parent%d\n",i);
lockf(*fp,0,0); /*解锁*/
}
}
fclose(fp);
}
答案:
分析:
程序开始定义了文件读写指针用于打开指定的文件,当文件不存在时则自动创建。
然后有创建了一个进程p1,p1获得处理机执行,给文件读写指针加锁,这样,即使p1失去处理机,其他获得处理机的进程也无法访问文件指针指向的文件,当p1再次获得处理机后继续执行直至进程p1结束并解锁;p1结束后父进程获得处理机执行又创建了进程p2,p2获得处理机执行,也给文件指针加锁,同理直至p2运行完解锁;p2结束后父进程获得处理机,父进程也给文件指针加锁,直至父进程执行完毕解锁,程序结束。
3 进程的控制实验
实验内容
1、用fork()创建一个进程,再调用exec()用新的程序替换该子进程的内容
2、利用wait()来控制进程执行顺序
(1)如何更新子进程内容?
答案:
系统调用exec()将一个可执行的二进制文件覆盖在新进程的用户级上下文的存储空间上,改变调用进程的执行代码,从而形成新进程。
用fork()建立子进程,然后在子进程中使用exec(),这样就实现了父进程与一个与它完全不同子进程的并发执行。
(2)可执行文件加载时进行了哪些处理?
答案:
可执行文件加载时首先是创建一个新进程的fork系统调用,然后用于实现进程自我终止的exit系统调用;改变进程原有代码的exec系统调用;用于将调用进程挂起并等待子进程终止的wait系统调用;获得进程标识符的getpid系统调用等处理过程。
(3)什么是进程同步?
wait()是如何实现进程同步的?
答案:
把异步环境下的一组并发进程因直接制约而互相发送消息而进行互相合作、互相等待,使得各进程按一定的速度执行的过程称为进程间的同步。
(百科的)
进程同步:
首先程序在调用fork()机那里了一个子进程后,马上调用wait(),使父进程在子进程调用之前一直处于睡眠状态,这样就使子进程先运行,子进程运行exec()装入命令后,然后调用wait(0),使子进程和父进程并发执行,实现进程同步。
实验过程中遇到的问题解决办法与实验体会Q3(10分)
得分:
在这次的实验中我遇到不少的问题:
1.在第二个实验中的最后一个程序中要用到exit()函数,而按照老师的代码中,没有这个头文件,所以运行起来的时候有错误,后来通过自己查找一下资料解决了!
2.通过这次实验我会有lockf(0,0,0)加锁这个函数了,还有解锁,对进程互斥有了一个大概的了解。
3.在做那个to_be_locked.txt这个程序中遇到不少问题,程序中一直提示有警告,实验我就不断地重覆看那个代码,的确发现有不妥,文件应该是用FILE的,但是代码中用了int,但是我改了FILE还是出现问题,最后安装老师代码运行了,虽然有警告,但是程序还是可以正常运行,结果也输出在to_be_locked.tx中!
在这个过程中还是挺有意思的,至少我也学到了不是东西和提高了我对实验的兴趣!
4.在最后一个实验中,主要是看exec()、wait()和exit()的介绍,从中了解到了另外一种创建子进程的函数和了解了wait()的一些信息和exit()的执行过程!
5.最后的那三个思考题我是百科得来的答案,但是我很认真地去理解其中的意思了,也明白了这个过程了!
评阅教师特殊评语:
评阅教师:
日期: