操作系统实验1.docx

上传人:b****5 文档编号:6498316 上传时间:2023-01-07 格式:DOCX 页数:14 大小:129.99KB
下载 相关 举报
操作系统实验1.docx_第1页
第1页 / 共14页
操作系统实验1.docx_第2页
第2页 / 共14页
操作系统实验1.docx_第3页
第3页 / 共14页
操作系统实验1.docx_第4页
第4页 / 共14页
操作系统实验1.docx_第5页
第5页 / 共14页
点击查看更多>>
下载资源
资源描述

操作系统实验1.docx

《操作系统实验1.docx》由会员分享,可在线阅读,更多相关《操作系统实验1.docx(14页珍藏版)》请在冰豆网上搜索。

操作系统实验1.docx

操作系统实验1

 

实验报告书

 

学生姓名高雪

学号10101020203

班级计10A-2

 

2011—2012学年第一学期

 

《计算机操作系统》实验报告

实验名称

进程管理实验

实验序号

实验日期

2012/12/16

实验人

高雪

一、实验目的和要求

1.加深对进程概念的理解,明确进程和程序的区别

2.进一步认识并发执行的实质

3.分析进程争用资源的现象,学习解决进程互斥的方法

4.了解Linux系统中进程通信的基本原理

二、相关背景知识

1.进程的定义

进程是操作系统结构的基础;是一个正在执行的程序;计算机中正在运行的程序实例;可以分配给处理器并由处理器执行的一个实体;由单一顺序的执行显示,一个当前状态和一组相关的系统资源所描述的活动单元。

进程是一个独立的可以调度的活动,是一个抽象实体,当它执行某个任务时,将要分配和释放各种资源。

总之,程序在处理机上执行时的活动称为进程。

具有并发性,动态性,独立性,异步性。

2.进程控制

进程有三个状态。

就绪态,阻塞态,运行态。

系统通过使用一些具有特定功能的程序段来创建、撤销进程以及完成进程各状态间的转换,从而达到多进程高效率并发执行和协调、实现资源共享的目的。

期中,运行态可以转换到阻塞,就绪。

阻塞可以转换到就绪,就绪可以到运行。

3.软中断

软中断是对硬中断的一种模拟,发送软中断就是向接受进程的proc结构中的相应项发送一个特定意义的信号。

软中断必须等到接收进程执行时才能生效。

4.管道

在Linux中,管道是一种使用非常频繁的通信机制。

是一个先进先出,大小固定的缓冲区,用于两个进程之间的单向数据传递。

当管道有空间时,写进程把数据送入管道,否则将被阻塞;如果管道中没有数据或者读进程需要的数据多于其中的数据,读进程被阻塞,否则执行读进程的请求。

三、实验内容

1.进程的创建

编写一段程序,使用系统调用fork()创建两个子进程。

当此程序运行时,在系统中有一个父进程和两个子进程活动。

让每一个进程在屏幕上显示一个字符:

父进程显示字符“a”;子进程分别显示字符“b”和字符“c”。

试观察记录屏幕上的显示结果,并分析原因。

2.进程的控制

修改已有程序,将每个进程输出一个字符改为每个进程输出几行字符,再观察程序执行时屏幕上的现象,并分析原因。

如果在程序中使用系统调用lockf()来给每一个进程加锁,可以实现进程之间的互斥,观察并分析出现的现象。

3.进程的软中断通信

使用系统调用fork()创建两个子进程,再用系统调用signal()让父进程捕捉键盘上来的中断信号(即按Del键);当捕捉到中断信号后,父进程用系统调用kill()向两个子进程发出信号,子进程捕捉到信号后分别输出下列信息后终止:

Childprocess1iskilledbyparent!

Childprocess2iskilledbyparent!

父进程等待两个子进程终止后,输出如下的信息后终止:

Parentprocessiskilled!

4.进程的管道通信

编制一段程序,实现进程的管道通信。

使用系统调用pipe()建立一条管道线;两个子进程P1和P2分别向管道各写一句话:

Child1issendingamessage!

Child2issendingamessage!

而父进程则从管道中读出来自于两个子进程的信息,显示在屏幕上。

要求父进程先接收P1

来的消息,然后再接收P2发来的消息

四、关键数据结构与函数的说明

1.fork()函数

Fork函数用于创建一个新进程(子进程),返回整数。

正确返回:

等于0,创建子进程;大于0,从父进程返回的子进程的ID值。

错误返回:

等于-1,即进程创建失败。

2.wait()函数

wait()函数常用来控制父进程与子进程的同步。

在父进程中调用wait(),则父进程被阻塞,进入等待队列,等待子进程结束。

当子进程结束时,会产生一个终止状态字,系统会向父进程发出SIGCHLD信号。

当接到信号后,父进程提取子进程的终止状态字,从wait()函数返回继续执行原程序。

3.exit()函数

exit()函数是进程结束最常调用的函数。

在正常终止时,exit()函数返回进程结束状态。

4.kill()函数

kill()函数用于结束执行中的程序或者任务。

 

5.signal()

signal()函数是允许调用进程控制软中断信号的处理。

6.pipe()函数

pipe函数用于创建一个管道

五、编译与执行过程截图

 

1.进程的创建

 

执行后出现acb和abc两种不同情况

2.进程的控制

(1)加锁情况:

(2)没有加锁的情况

 

3.进程的软中断通信

4.进程的管道通信

 

六、实验结果与分析

1.进程的创建:

实验一为进程创建,由以上截图可以看到产生了不同的结果,即acb和abc。

最初只有acb一种情况,反复执行之后,会出现abc。

原因很简单,就是因为进程的特性:

并发性。

进程之间是并发执行的,并发只说一段时间内同时进行。

第一个输出一定是a,因为a在bc之外优先执行,而在执行bc的时候,2者会随机出现,多数情况会是acb,若想更快的见到abc,可以讲c语句变长,如改为thisiscchild.这样进程需要的时间就稍长,后一个会先出现了。

但宏观来看,还是并行的。

2.进程的控制

实验二为进程控制,分为不加锁和加锁的情况,产生的结果不同,在不加锁的情况下,还有由于进程的执行具有并发性这个特征,因此会产生字符交叉的情况,即某一个进程在自己的时间片当中使用处理机,但是当时间片结束,还没有完成,但也必须由下一个进程接管处理机,因为它就进入了阻塞的状态。

多个进程反复出现,所以就出现了输出的字符交叉的情况。

但是,当我们对进程加锁后,就表明只能由该程序占用处理机,必须这些完这段程序才能执行下一段,因为不会出现交叉的情况,这个就是锁的作用。

 

3.进程的软中断通信

进程的软中断控制,使用系统调用fork()创建两个子进程,再用系统调用signal()让父进程捕捉键盘上来的中断信号(即按Del键);当捕捉到中断信号后,父进程用系统调用kill()向两个子进程发出信号,子进程捕捉到信号后分别输出下列信息后终止:

Childprocess1iskilledbyparent!

Childprocess2iskilledbyparent!

父进程等待两个子进程终止后,输出如下的信息后终止:

Parentprocessiskilled!

 

4.进程的管道通信

实验四为进程通道管理:

管道机制必须提供以下三方面的协调能力:

(1)首先要判断读写进程双方是否存在,只有确定读进程和写进程都存在的情况下,才能够通过管道进行通信。

(2)同步:

当写进程完成任务,把要求的数据写入管道后,便会睡眠等待。

直到读进程将管道中的数据读取取出后,再把写进程唤醒。

当读进程试图从一空管道中读取数据时,也应睡眠等待,直至写进程将数据写入管道后,才将其唤醒。

(3)互斥:

当一个进程正对pipe进行读/写操作时,另一进程必须等待,程序中使用lock(fd[1],1,0)函数实现对管道的加锁操作,用lock(fd[1],0,0)解除管道的锁定

七、调试时遇到的问题及解决方法(提供BUG截屏)

 

八、调试后的程序源代码

1.创建进程

#include

main()

{

intp1,p2;

while((p1=fork())==-1);//fork为系统调用函数,作用是创建一个进程

if(p1==0)//fork返回0代表子进程在执行

putchar('b');//打印字母b代表子进程1执行

else//父进程返回子进程的ID

{

while((p2=fork())==-1);//创建子进程2

if(p2==0)

putchar('c');//打印字母c代表子进程2执行

else

putchar('a');//打印字母a代表父进程执行

}

}

2.进程的控制

(1)未加锁:

#include

main()

{

intp1,p2,i;

while((p1=fork())==-1);

if(p1==0)

for(i=0;i<50;i++)

printf("child%d\n",i);

else

{

while((p2=fork())==-1);

if(p2==0)

for(i=0;i<50;i++)

printf("son%d\n",i);

else

for(i=0;i<50;i++)

printf("daughter%d\n",i);

}

}

(2)加锁:

#include

#include//系统调用lockf的头文件

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.进程的软中断通信

#include

#include

#include

voidwaiting(),stop();

intwait_mark;

main()

{

intp1,p2;

while((p1=fork())==-1);

if(p1>0)

{

while((p2=fork())==-1);

if(p2>0)

{

printf("parents\n");

wait_mark=1;

signal(SIGINT,stop);

waiting(0);

kill(p1,16);

kill(p2,17);

wait(0);

wait(0);

printf("parentprocessiskilled!

\n");

exit(0);

}

Else

{

printf("p2\n");

wait_mark=1;

signal(17,stop);

signal(SIGINT,SIG_IGN);

waiting();

lockf(1,1,0);

printf("childprocess2iskilledbyparent!

\n");

lockf(1,0,0);

exit(0);

}

}

Else

{

printf("p1\n");

wait_mark=1;

signal(16,stop);

signal(SIGINT,SIG_IGN);

waiting();

lockf(1,1,0);

printf("childprocess1iskilledbyparent!

\n");

lockf(1,0,0);

exit(0);

}

}

voidwaiting()

{

while(wait_mark!

=0);

}

voidstop()

{

wait_mark=0;

}

4.进程的管道通信

#include

#include

#include

intpid1,pid2;

main()

{

intfd[3];

charOutPipe[100],InPipe[100];

pipe(fd);

while((pid1=fork())==-1);

if(pid1==0)

{

printf("p1\n");

lockf(fd[1],1,0);

sprintf(OutPipe,"Child1processissendingamessage!

");

OutPipe

write(fd[1],OutPipe,50);

sleep

(1);

lockf(fd[1],0,0);

exit(0);

}

else

{

while((pid2=fork())==-1);

if(pid2==0)

{

printf("p2\n");

lockf(fd[1],1,0);

sprintf(OutPipe,"Child2processissendingamessage!

");

OutPipe

write(fd[1],OutPipe,50);

sleep

(1);

lockf(fd[1],0,0);

exit(0);

}

else

{

printf("parent\n");

wait(0);

read(fd[0],InPipe,50);

printf("%s\n",InPipe);

wait(0);

read(fd[0],InPipe,50);

printf("%s\n",InPipe);

exit(0);

}}}

九、实验体会

第一次接触Linux系统,使用起来非常不习惯,但是在了解了终端上的一些指令操作后,感觉还可以。

这个实验一共有四个小题,第一个与第二个都涉及到了进程的概念,以及进程具有并发性的这个特点。

通过前2个实验,我对与进程是并发执行的有了深刻的认识。

以前我就觉得它就跟C语言一样,一行一行的执行,不会出现什么跳跃,交错之类的。

简而易见,以前理解错了。

进程之间确实是并发执行的。

另外的2个实验一个是中断的处理,一个是管道的应用。

前者比较抽象,用编程实现的时候比较不好想。

后者还比较容易,我理解的就是管道就是一个中介,数据都放到管道中。

写进程将读进程需要的数据写到管道中,而读进程则借助于管道将写进程写入的数据读取出来。

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 医药卫生

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1