当前位置:文档之家› 北方工业大学《计算机操作系统》实验报告——进程管理

北方工业大学《计算机操作系统》实验报告——进程管理

2.进程的控制:
<程序一>子进程和父进程输出字符串有相互嵌插的现象。由于进程并发执行时的调度顺序和父子进程的抢占处理机问题,输出字符串的顺序和先后随着执行的不同而发生变化。这与打印单字符的结果相同。
<程序二>因为lockf(1,1,0)锁定标准输出设备,lockf(1,0,0)解锁标准输出设备,在lockf(1,1,0)与lockf(1,0,0)中间的for循环输出不会被中断,加锁与不加锁效果不相同。
printf("bbb");
lockf(1,0,0);
exit(0);
}
else
{
lockf(1,1,0);
for(i=0;i<10000;i++)
printf("ccc");
lockf(1,0,0);
exit(0);
}
}
}
/*第3题33.c*/
#include<stdio.h>
#include<signal.h>
2.在3题中,因为我自己的粗心导致注释行出错,使kill(p1,16)函数没有调用成功,只出现了“parent process is killed!”,没有输出其余两句。在出现错误之后我立马去检查,便解决了这个问题。
3.在第3题中,要求让父进程捕捉键盘上来的中断信号(即按Del键),但是在实际实验中当我按下Del键时并没反映,后来经查资料,知道了在Linux系统下应该是按下Ctrl+C键。
进程结束最常用的方法是调用exit函数,在main函数中调用的return,最终也是调用exit,这些都属于进程的正常终止。
4.lockf(files,mode,size):用于锁定文件的某些段或者整个文件
files是文件描述符;mode是锁定和解锁:1表示锁定,0表示解锁.size是锁定或解锁的字节数,为0,表示从文件的当前位置到文件尾.。
lockf(1,0,0);
exit(0);
}
}
else
{
wait_mark=1;
signal(16,stop);
signal(SIGINT,SIG_IGN);/*忽略^c信号*/
while(wait_mark!=0)
lockf(1,1,0);
printf("child process1 is killed by parent!\n");
main()
{
intp1,p2,i;
if(p1=fork())
{
lockf(1,1,0);
for(i=0;i<10000;i++)
printf("aaa");
lockf(1,0,0);
exit(0);
}
else
{
if(p2=fork())
{
lockf(1,1,0);
for(i=0;i<10000;i++)
五、编译与执行过程截图
1.进程的创建
进程的创建:系统调用fork()创建两个子进程。当程序运行时,系统中有一个父进程和两个子进程活动。父进程显示字符“a”;子进程分别显示字符“b”和字符“c”。如图,有acb;abc两种情况出现了
2.进程的控制
子进程和父进程互相抢占处理机,导致输出“乱序”现象的出现,可以看到在“bbb”中出现了“aaa”。
exit(0);
}
else
{
while((pid2=fork( ))==-1);
if(pid2==0)
{
lockf(fd[1],1,0);/*互斥*/
sprintf(outpipe,"child 2 process is sending message!");
write(fd[1],outpipe,50);
exit(0);
}
}
}
九、实验体会
#include<unistd.h>
voidwaiting(),stop(),alarming();
intwait_mark;
main()
{
intp1,p2;
if(p1=fork())/*创建子进程p1*/
{
if(p2=fork())/*创建子进程p2*/
{
wait_mark=1;
signal(SIGINT,stop);/*接收到^c信号,转stop*/
八、调试后的程序源代码
/*第一题:creat.c*/
#include<stdio.h>
main( )
{
intp1,p2;
while((p1=fork( ))==-1);/*创建子进程p1*/
if(p1==0) putchar('b');
else
{
while((p2=fork( ))==-1);/*创建子进程p2*/
if(pid1==0)
{
lockf(fd[1],1,0);
sprintf(outpipe,"child 1 process is sending message!");/*把串放入数组outpipe中*/
write(fd[1],outpipe,50);/*向管道写长为字节的串*/
lockf(fd[1],0,0);
2.wait():进程的等待,常用来控制父进程与子进程的同步:
在父进程中调用wait函数,则父进程被阻塞,进入等待队列,等待子进程结束。当子进程结束时,会产生一个终止状态字,系统会向父进程发出SIGCHLD信号。当接收到信号后,父进程提取子进程的终止状态字,从wait返回继续执行原程序。
3.exit():结束进程
signal(SIGALRM,alarming);/*接受SIGALRM*/
waiting();
kill(p1,16);/*向p1发软中断信号*/
kill(p2,17);/*向p2发软中断信号*/
wait(0);/*同步*/
wait(0);
printf("parent process is killed!\n");
Child 1 is sending a message!
Child 2 is sending a message!
而父进程则从管道中读出来自于两个子进程的信息,先接收P1发来的消息,然后再接收P2发来的消息,显示在屏幕上。
六、实验结果与分析
1.进程的创建运行结果:acb,abc,其实,从进程执行并发来看,输出abc的任何排列都是有可能的。因为fork()创建进程所需的时间虽然可能多于输出一个字符的时间,但各个进程的时间片的获得却不是一定是顺序的,父进程与子进程的输出内容会叠加在一起,输出次序带有随机性。
实验报告书
学生姓名
学号
班级
2012 — 2013学年第一学期
《计算机操作系统》实验报告
实验名称
进程管理
实验序号
1
实验日期
2012年12月
实验人
一、实验目的和要求
1.加深对进程概念的理解,明确进程和程序的区别
2.进一步认识并发执行的实质
3.分析进程争用资源的现象,学习解决进程互斥的方法
4.了解Linux系统中进程通信的基本原理
5.signal(int signum,void(* handler)(int)):signal()会依参数signum指定的信号编号来设置该信号的处理函数。当指定的信号到达时就会跳转到参数handler指定的函数执行。
6.kill(pid_t pid,int sig),可以用来送参数sig指定的信号给参数pid指定的进程。
因为加锁了,所以各子进程和父进程各自打印出各自的字符串,并没有出现穿插的现象。
3.进程的软中断通信
使用系统调用fork()创建两个子进程,再用系统调用signal()让父进程捕捉键盘上来的中断信号(即按Del键);当捕捉到中断信号后,父进程用系统调用kill()向两个子进程发出信号,子进程捕捉到信号后分别输出:
exit(0);
}
else
{
wait_mark=1;
signal(17,stop);
signal(SIGINT,SIG_IGN);/*忽略^c信号*/
while(wait_mark!=0);
lockf(1,1,0);
printf("child process2 is killed by parent!\n");
4.进程的管道:进程p1和进程p2分别从管道的一端向管道输入了信息,父进程从管道的另一端读出了信息,先为p1的消息再为p2的消息,连接了一个读进程和一个写进程实现他们之间通信的一个共
享。首先,通过pipe()先创建了一个管道,子进程p1,p2是共享输入端的,所以要通过lockf()进行加锁解锁实现互斥,并且是先由p1向管道发送消息,然后是p2。父进程通过wait(0)等待子进程结束后从管道读取消息。
#include<unistd.h>
#include<signal.h>
#include<stdio.h>
intpid1,pid2;
main( )
{
intfd[2];
charoutpipe[100],inpipe[100];
pipe(fd);/*创建一个管道*/
while((pid1=fork( ))==-1);
七、调试时遇到的问题及解决方法(提供BUG截屏)
1.在第2(1)题中因为循环次数太少,所以并没有出现乱序的情况,后来老师提醒我们可以把循环次数大大增加,因为处理机的速度是很快的,如果不把循环次数i的值设为比较大的数的话,很可能体现不出来进程并发执行时的调度顺序和父子进程的抢占处理机问题,这个数字的设定也因机器而异,本来在我的程序中i的设置值为500,后来我改为了10000,才出现了乱序的现象。
相关主题