实验二进程通信管道共享内存.docx

上传人:b****5 文档编号:4484904 上传时间:2022-12-01 格式:DOCX 页数:12 大小:1.25MB
下载 相关 举报
实验二进程通信管道共享内存.docx_第1页
第1页 / 共12页
实验二进程通信管道共享内存.docx_第2页
第2页 / 共12页
实验二进程通信管道共享内存.docx_第3页
第3页 / 共12页
实验二进程通信管道共享内存.docx_第4页
第4页 / 共12页
实验二进程通信管道共享内存.docx_第5页
第5页 / 共12页
点击查看更多>>
下载资源
资源描述

实验二进程通信管道共享内存.docx

《实验二进程通信管道共享内存.docx》由会员分享,可在线阅读,更多相关《实验二进程通信管道共享内存.docx(12页珍藏版)》请在冰豆网上搜索。

实验二进程通信管道共享内存.docx

实验二进程通信管道共享内存

操作系统实验报告

 

实验二:

进程通信

(一)——管道及共享内存

一、实验目的

∙了解进程之中相互通信的方式

∙加深对管道通信的了解

∙了解共享内存通信的程序设计方法

∙了解和熟悉Linux支持的共享存储区机制

二、实验内容和步骤

任务一、

(1)阅读以上父子进程利用管道进行通信的例子(例1),写出程序的运行结果并分析。

(2)编写程序:

父进程利用管道将一字符串交给子进程处理。

子进程读字符串,将里面的字符反向后再交给父进程,父进程最后读取并打印反向的字符串

任务二、

1)阅读例2的程序,运行一次该程序,然后用ipcs命令查看系统中共享存储区的情况,再次执行该程序,再用ipcs命令查看系统中共享内存的情况,对两次的结果进行比较,并分析原因。

最后用ipcrm命令删除自己建立的共享存储区。

(有关ipcs和ipcrm介绍见后面一页)

(2)每个同学登陆两个窗口,先在一个窗口中运行例3程序1(或者只登陆一个窗口,先在该窗口中以后台方式运行程序1),然后在另一个窗口中运行例3程序2,观察程序的运行结果并分析。

运行结束后可以用ctrl+c结束程序1的运行。

(3)编写程序:

使用系统调用shmget(),shmat(),shmdt(),shmctl(),编制程序。

要求在父进程中生成一个30字节长的私有共享内存段。

接下来,设置一个指向共享内存段的字符指针,将一串大写字母写入到该指针指向的存贮区。

调用fork()生成子进程,让子进程共享内存段中的内容。

接着,将大写字母改成小写,子进显示程修改共享内存中的内容。

之后,子进程将脱接共享内存段并退出。

父进程在睡眠5秒后,在此显示共享内存段中的内容(此时已经是小写字母)。

三、代码及运行结果分析

1.任务1

(1)

①代码:

#include

#include

#include

#include

#include

#include

intmain()

{

intx,fd[2];

charbuf[30],s[30];

pipe(fd);

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

if(x==0){

close(fd[0]);

printf("ChildProcess!

\n");

strcpy(buf,"Thisisanexample\n");

write(fd[1],buf,30);

exit(0);

}

else{

close(fd[1]);

printf("ParentProcess!

\n");

read(fd[0],s,30);

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

}

}

②截图:

③结果和分析:

创建一个管道,调用fork()函数产生两个进程,我的系统优先先执行父进程,比较疑惑,既然这样,管道中并没有数据是如何得出最后结果的,后来XX了一下解释说是因为管道本身是一种同步机制,并且printf执行的时间要比其他程序时间长得多,才会这样。

然后执行子程序,将数据写入管道,然后父程序打印出来

2.任务1

(2)

①代码:

#include

#include

#include

#include

#include

#include

voidfanzhuan(char*s){

char*p=s+strlen(s)-1;

chartemp;

while(s

temp=*p;

*p--=*s;

*s++=temp;

}

}

intmain()

{

inti,x,fd[2];

charbuf[20],s[20],m[20];

strcpy(buf,"Thisisanexample\n");

pipe(fd);

write(fd[1],buf,20);

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

if(x==0){

printf("ChildProcess!

\n");

read(fd[0],s,20);

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

fanzhuan(s);

write(fd[1],s,20);

exit(0);

}

else{

wait(NULL);

close(fd[1]);

printf("ParentProcess!

\n");

read(fd[0],m,20);

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

}

}

②截图:

3.任务2

(1)

①代码:

#include

#include

#include

#include

#include

intmain(){

key_tkey=105;

intshmid_1,shmid_2;

if((shmid_1=shmget(key,1000,0644|IPC_CREAT))==-1){

perror("shmgetshmid_1");

exit

(1);

}

printf("Firstsharedmemoryidentifieris%d\n",shmid_1);

if((shmid_2=shmget(IPC_PRIVATE,20,0644))==-1){

perror("shmgetshmid_2");

exit

(2);

}

printf("Secondsharedmemoryidentifieris%d\n",shmid_2);

exit(0);

}

②截图:

③结果和分析:

两次运行结束后,第二个共享标识符不一样,然后在每一次的ipcs查看共享存储区的时候,最后一行也是不一样的。

原因是分配了两次,然后第一次有key值,第二次是没有的。

4.任务2

(2)

①代码:

程序1:

#include

#include

#include

#include

#include

#include

#include

#defineSHMKEY105

#defineK1024

intshmid;

intmain(){

inti,*pint;

char*addr;

externvoid*shmat();

externcleanup();

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

signal(i,cleanup);

shmid=shmget(SHMKEY,16*K,0777|IPC_CREAT);

addr=shmat(shmid,0,0);

printf("addr0x%x\n",addr);

pint=(int*)addr;

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

*pint++=i;

pause();

}

cleanup(){

shmctl(shmid,IPC_RMID,0);

exit(0);

}

程序2:

#include

#include

#include

#include

#include

#include

#include

#defineSHMKEY105

#defineK1024

intshmid;

intmain(){

inti,*pint;

char*addr;

externvoid*shmat();

shmid=shmget(SHMKEY,8*K,0777);

addr=shmat(shmid,0,0);

pint=(int*)addr;

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

printf("%d\n",*pint++);

}

②截图:

③结果和分析:

程序

(1)后台运行的时候,先创建一个共享内存段,然后挂接,得到共享区的地址,并且输出这个地址,然后pint的首地址就是共享区首地址,向共享区里面输入1,2,3,4,5.。

155。

程序

(2)执行的时候首先先挂接到这个共享区,然后向从首地址开始遍历,输出其中的内容

5.任务2(3)

①代码:

#include

#include

#include

#include

#include

#include

#include

#include

intmain(){

key_tkey=105;

intshmid,p1,i;

char*addr,*pint,temp;

shmid=shmget(key,30,0644|IPC_CREAT);

addr=shmat(shmid,0,0);

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

*addr='A'+i;

addr++;

}

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

if(p1==0){

shmid=shmget(105,30,0644);

printf("success\n");

addr=shmat(shmid,0,0);

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

temp=*addr;

*addr=temp+32;

addr++;

}

addr=shmat(shmid,0,0);

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

shmdt(addr);

}

else{

sleep(5);

addr=shmat(shmid,0,0);

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

}

//printf("%s\n",addr);

shmctl(shmid,IPC_RMID,0);

exit(0);

}

②截图:

③结果和分析:

首先显示创建一个要求的共享区,然后挂接上去,得到共享区首地址,向共享区中输入一串大写字符串,然后调用fork(),生成一个子程序,先让挂接到共享区,并且获得首地址,然后修改大写字母变成小写字母,然后脱离,最后再次调用父程序,获得首地址,然后输出共享区的内容。

四、心得体会

在本次试验中,认识到了管道和共享内存的概念,这两种都是进程之中相互通信的非常高效的方式,管道一般多用于父进程和子进程之中,是一种同步机制。

共享内存用到的时候先要分配,然后获得地址,最后还需要释放。

需要注意的是,在修改共享内存中的值的时候,首先需要定位到共享内存的首地址,不然很容易会出错,其他程序用到共享内存的时候,首先也是需要先挂接到那边。

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

当前位置:首页 > 教学研究 > 教学计划

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

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