操作系统实验三进程管理实验报告.docx

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

操作系统实验三进程管理实验报告.docx

《操作系统实验三进程管理实验报告.docx》由会员分享,可在线阅读,更多相关《操作系统实验三进程管理实验报告.docx(19页珍藏版)》请在冰豆网上搜索。

操作系统实验三进程管理实验报告.docx

操作系统实验三进程管理实验报告

计算机与信息工程学院实验报告

姓名

学号

专业

软件工程

年级

2017级

课程

操作系统

主讲教师

党兰学

实验时间(年月日时)

2019年10月23日

实验地点

计算机学院201机房

辅导教师

党兰学

实验题目

进程管理

实验目的

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

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

3.了解父进程和子进程之间的关系;

4.查看进程管理命令。

实验环境(硬件和软件)

硬件:

PC机软件:

OracleVMVirtualboxLinux

一、实验内容

1.练习在shell环境下编译执行程序

(注意:

①在vi编辑器中编写名为的c语言源程序

②用linux自带的编译器gcc编译程序,例如:

gcc–otest

③编译后生成名为的可执行文件;

④最后执行分析结果;命令为:

./test)

注意:

linux自带的编译程序gcc的语法是:

gcc–o目标程序名源程序名,例如:

gcc–osample1,然后利用命令:

./sample来执行。

如果仅用“gcc源程序名”,将会把任何名字的源程序都编译成名为的目标程序,这样新编译的程序会覆盖原来的程序,所以最好给每个源程序都起个新目标程序名。

2.进程的创建

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

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

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

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

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

3.分析程序

实验内容要在给出的例子程序基础上,根据要求进行修改,对执行结果进行分析。

二、实验步骤

1.利用fork()创建一个小程序

(1)编写程序

#include

main()

{

inti=5;

pid_tpid;

pid=fork();

for(;i>0;i--)

{

if(pid<0)

printf("errorinfork!

");

elseif(pid==0)

printf("iamthechildprocess,myprocessidis%dandi=%d\n",getpid(),i);

else

printf("iamtheparentprocess,myprocessidis%dandi=%d\n",getpid(),i);

}

for(i=5;i>0;i--)

{

if(pid<0)

printf("errorinfork!

");

elseif(pid==0)

printf("thechildprocess,myprocessidis%dandi=%d\n",getpid(),i);

else

printf("theparentprocess,myprocessidis%dandi=%d\n",getpid(),i);

}

}

(2)运行程序

(3)分析程序

在这里,主程序先运行,在屏幕上输出一个a,之后两个子程序分别运行而输出c和b。

2子进程对存取空间的复制

(1)编写程序

(2)运行程序

(3)分析程序

通过scanf(“%d”,&i);语句读取一个整数存在i,之后创建两个子程序,输入10后,子程序运行,之后经过一些读取赋值操作,输出i的值。

3父子进程执行进程分析

(1)编写程序

(2)运行程序

(3)程序分析

三次结果不同是因为printf(“Inwhichprocess\n”);所处位置经过变换,处于父子程序之后,父子程序之前和父程序之中。

4修改程序验证父子进程关系

(1)编写程序

文本代码:

#include

#include<>

#include<>

#include<>

#include<>

#include

#include

#include

#include<>

#defineMY_SHMKEYToend,input0whenprompted.\n\n");

printf("Inputanumber:

\n");

scanf("%d",&local);

while(local)

{

=0;

=-1;

=SEM_UNDO;

semop(semid,&semopbuf,1);/*P(S1)*/

*shmptr=local;

=1;

=1;

=SEM_UNDO;

semop(semid,&semopbuf,1);/*V(S2)*/

printf("Inputanumber:

\n");

scanf("%d",&local);

}

}

else/*actsasserver*/

{

semid=semget(MY_SEMKEY,2,IPC_CREAT|0666);

shmptr=(int*)shmat(shmid,0,0);

semval=1;

semctl(semid,0,SETVAL,semval);/*setS1=1*/

semval=0;

semctl(semid,1,SETVAL,semval);/*setS2=0*/

signal(SIGINT,sigend);

signal(SIGTERM,sigend);

printf("ACTCONSUMER!

!

!

Toend,tryCtrl+Corusekill.\n\n");

while

(1)

{

=1;

=-1;

=SEM_UNDO;

semop(semid,&semopbuf,1);/*P(S2)*/

printf("Sharedmemorysetto%d\n",*shmptr);

=0;

=1;

=SEM_UNDO;

semop(semid,&semopbuf,1);/*V(S1)*/

}

}

}

voidsigend(intsig)

{

shmctl(shmid,IPC_RMID,0);

semctl(semid,IPC_RMID,0);

exit(0);

}

(2)运行程序

(3)分析程序

本示例主要体现进程间的直接制约关系,由于使用共享存储区,也存在间接制约关系。

进程分为服务进程和客户进程,服务进程只有一个,作为消费者,在每次客户进程改变共享存储区内容时显示其数值。

各客户进程作为生产者,如果共享存储区内容已经显示(被消费),可以接收用户从键盘输入的整数,放在共享存储区。

编译后执行,第一个进程实例将作为服务进程,提示:

ACTCONSUMER!

!

!

Toend,tryCtrl+Corusekill.

服务进程一直循环执行,直到用户按Ctrl+C终止执行,或使用kill命令杀死服务进程。

其他进程实例作为客户进程,提示:

Actasproducer.Toend,input0whenprompted.

客户进程一直循环执行,直到用户输入0。

5模拟临界资源访问的示例程序

(1)编写程序

文本代码:

#include

#include<>

#include<>

#include<>

#include<>

#include

#include

#include<>

#defineMY_SHMKEYn");

shmptr->top=MAX_BLOCK-1;

for(i=0;i

shmptr->stack[i]=MAX_BLOCK-i;

sleep(1000000);/*causesleepforever.*/

}

}

voidsigend(intsig)

{

shmctl(shmid,IPC_RMID,0);

semctl(semid,IPC_RMID,0);

exit(0);

}

voidrelblock(void)

{

if<0)

{

printf("Noblocktorelease!

");

return;

}

shmptr->top++;

shmptr->stack[shmptr->top]=[];

}

intgetblock(void)

{

if(shmptr->top<0)

{

printf("Nofreeblocktoget!

");

return;

}

[++]=shmptr->stack[shmptr->top];

shmptr->top--;

}

voidshowhelp(void)

{

printf("\navailableCOMMAND:

\n\n");

printf("help\tlistthishelp\n");

printf("list\tlistallgottenblocknumber\n");

printf("get\tgetanewblock\n");

printf("rel\treleasethelastgottenblock\n");

printf("end\texitthisprogram\n");

}

voidshowlist(void)

{

inti;

printf("Listallgottenblocknumber:

\n");

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

printf("%d\t",[i]);

}

voidgetcmdline(void)

{

printf("\n>");

fgets(cmdbuf,MAX_CMD-1,stdin);

}

(2)运行程序

(3)程序分析

本示例的临界资源是一个建立在共享存储区的栈,由服务进程建立并初始化。

初始状态下共享栈满,里面顺序放置一系列正整数(自栈顶向下:

1,2,3...),代表空闲块号。

客户进程利用共享栈进行数据块的分配和释放,以得到、归还一个块号代表,并不进行任何后续操作。

程序中getblock过程从共享栈中弹出一个块号(分配),relblock过程把一个已分配块号压入共享栈(释放)。

为简单起见,已分配块号在本地也使用栈结构保存,因而每次释放的是最后分配的块号。

编译后执行,第一个进程实例将作为服务进程,提示:

NOOTHEROPERATIONbutpressCtrl+Corusekilltoend.

服务进程完成初始化后将进入睡眠状态,直到用户按Ctrl+C终止执行,或使用kill命令杀死服务进程。

其他进程实例作为客户进程,进入后首先有命令帮助提示,然后显示命令提示符“>”,在命令提示下可以使用的命令包括:

help显示可用命令

list列出所有已分配块号

get分配一个新块

rel释放最后分配块号

end退出程序

三、实验数据记录

1.

2.

3.

4.

5.

四、问题讨论

(1)在程序运行过程中出现一个错误,错误语句:

exit(0);

原因:

少了一个头文件:

#include<>

(2)心得体会:

通过本次实验我了解了fork()函数等关于进程应用的函数并且学会了父子进程的各种基本操作,同时我也了解到做实验要谨慎加小心,一点差错就会导致全局崩溃。

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

当前位置:首页 > 初中教育

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

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