您好,欢迎来到二三娱乐。
搜索
您的当前位置:首页操作系统原理 进程通信共享内存

操作系统原理 进程通信共享内存

来源:二三娱乐


课程实践报告书

课程名称: 操作系统原理

题 目: 进程通信-共享内存

学生姓名: 专 业: 计算机科学与技术(网络方向)

班 别: 计科本113班

学 号: 1104402308

指导老师:

日 期: 2013 年 06 月 25 日

目录

一、基本要求 ......................................................................................................... 2 二、流程图分析...................................................................................................... 3 三、共享内存描述和使用.................................................................................... 10

3.1共享内存的概述...................................................................................... 10 3.2共享内存的原理...................................................................................... 11 3.3共享内存的分配...................................................................................... 11

3.4 共享内存的访问..................................................................................... 12 3.5共享内存的应用...................................................................................... 12 3.6共享内存的意义...................................................................................... 13 四、实验构思........................................................................................................ 13

4.1 main()的使用 ........................................................................................... 13 4.2 shmget()调用 ........................................................................................... 17 4.3 fork()的调用 ............................................................................................ 17 4.4 子进程调用shmat() ............................................................................... 17 4.5子进程调用shmdt() ................................................................................ 17 4.6 父进程调用 shmctl() ............................................................................. 18 4.7父进程调用shmat(),shmdt(),shmctl()..................................................... 18 五、实验的调试与测试........................................................................................ 18 六、实验结果........................................................................................................ 20 七、源程序............................................................................................................ 21 八、实验感受........................................................................................................ 25 九、参考文献........................................................................................................ 25

一、基本要求

1.1实验题目:进程通信共享内存

1.2实践目的:用代码实现进程通信共享内存

1.3实践内容:用C语言代码创建进程,实现进程通信共享内存(父进程和子进程通过共享内存实现信息的交流)

1.4实验环境:linux操作系统及gcc工具

二、流程图分析

图1-1

如图1-1首先父进程调用shmget()函数建立一个共享内存,该函数返回一内存的标识符。

图1-2

如图1-2父进程调用fork()产生一个子进程

图1-3

如图1-3子进程调用shmat()函数将该共享内存连接到自己的虚存空间中

图1-4

如图1-4写完数据后,子进程调用shmdt()函数断开与该进程的连接

如图1-5

如图1-5父进程调用shmctl()函数得到关于这块共享内存的相关信息,并打印出来

图1-6

如图1-6父进程调用shmat()函数将这块共享内存连接到自己的虚存空间

图1-7

如图1-8父进程调用shmdt()函数断开与该共享内存的连接

图1-8

如图1-8父进程调用shmctl()函数,销毁该共享进程。

三、共享内存描述和使用

3.1共享内存的概述

针对消息缓冲需要占用CPU进行消息复制的缺点,操作系统提供了一种进程间直接进

行数据交换的通信方式——共享内存。顾名思义,这种通信方式允许多个进程共享同一块物理内存空间来实现进程之间的信息交换,其特点是没有中间环节,直接将共享的内存页面通过附接,映射到相互通信的进程各自的虚拟地址空间中,从而使多个进程可以直接访问同一个物理内存页面,如同访问自己的私有空间一样(但实质上不是私有的而是共享的)。因此这种进程间通信方式是在同一个计算机系统中的诸进程间实现通信的最快捷的方法,而它的局限性也在于此,即共享内存的诸进程必须共处同一个计算机系统,有物理内存可以共享才行。

3.2共享内存的原理

共享内存是由IPC为一个进程所创建并且出现在这个进程的地址空间中的一段特殊的地址序列。其他的进程可以将同样的共享内存段关联到他们自己的地址空间中。所有的进程都可以访问这段内存地址,就如同这段内存是由malloc所分配的。如果一个进程写入共享内存,这些改变立即就可以为访问相同共享内存的其他进程所见。 就其自身而言,共享内存并没有提供任何共享方法。并没有自动的方法来阻止在第一个进程完成写入共享内存之前第二个进程开始读取共享内存。

3.3共享内存的分配

要使用一块共享内存,进程必须首先分配它。随后需要访问这个共享内存块的每一个进程都必须将这个共享内存绑定到自己的地址空间中。当完成通信之后,所有进程都将脱离共享内存,并且由一个进程释放该共享内存块。

尽管每个进程都有自己的内存地址,不同的进程可以同时将同一个内存页面映射到自己的地址空间中,从而达到共享内存的目的。

分配一个新的共享内存块会创建新的内存页面。因为所有进程都希望共享对同一块内存的访问,只应由一个进程创建一块新的共享内存。再次分配一块已经存在的内存块不会创建新的页面,而只是会返回一个标识该内存块的标识符。一个进程如需使用这个共享内存块,则首先需要将它绑定到自己的地址空间中。这样会创建一个从进程本身虚拟地址到共享页面的映射关系。当对共享内存的使用结束之后,这个映射关系将被删除。当再也没有进程需要使用这个共享内存块的时候,必须有一个(且只能是一个)进程负责释放这个被共享的内存页面。

所有共享内存块的大小都必须是系统页面大小的整数倍。系统页面大小指的是系统中单个内存页面包含的字节数。进程通过调用shmget来分配一个共享内存块。

该函数的第二个参数指定了所申请的内存块的大小。因为这些内存块是以页面为单位进行分配的,实际分配的内存块大小将被扩大到页面大小的整数倍。

3.4 共享内存的访问

要让一个进程获取对一块共享内存的访问,这个进程必须先调用 shmat(SHared Memory Attach,绑定到共享内存)。将 shmget 返回的共享内存标识符 SHMID 传递给这个函数作为第一个参数。该函数的第二个参数是一个指针,指向您希望用于映射该共享内存块的进程内存地址;如果您指定NULL则Linux会自动选择一个合适的地址用于映射。

3.5共享内存的应用

共享内存的通信方式是通过将可以共享的内存缓冲区直接附加到进程的虚拟地址空间

中来实现的,因此,这些进程之间的读写操作的同步问题操作系统无法实现,必须由诸共享该内存的进程去控制。另外,由于内存实体存在于计算机系统中,所以只能由处于同一个计算机系统中的诸进程共享。以上两点是共享内存通信的缺点,但是它提供了诸进程直接读写信息,无须复制,因而方便快捷的进程间通信方式,适用于信息量大且操作频繁的场合。

3.6共享内存的意义

共享内存是进程间通信中最简单的方式之一。共享内存允许两个或更多进程访问同一块内存,就如同 malloc() 函数向不同进程返回了指向同一个物理内存区域的指针。当一个进程改变了这块地址中的内容的时候,其它进程都会察觉到这个更改。 所有进程共享同一块内存,共享内存在各种进程间通信方式中具有最高的效率。访问共享内存区域和访问进程独有的内存区域一样快,并不需要通过系统调用或者其它需要切入内核的过程来完成。同时它也避免了对数据的各种不必要的复制。 四、实验构思

4.1 main()的使用

int main()

{

int shmid;

char *shmaddr;

strut shmid_ds buf;

shmid=shmget(KEY,SIZE,IPC_CREAT | 0600);

if(shmid==-1)

{

printf(\"create share memory failed:%s\

return 0;

}

if(fork()==0)

{

sleep(2);

shmaddr=(char *)shmat(shmid,NULL,0);

if(shmaddr==(void*)-1)

{

printf(\"connect to the share memory failed:%s\

return 0;

}

strcpy(shmaddr,\"hello,this is shared data.\\n\");

shmdt(shmaddr);

exit(0);

}else

{

wait(0);

shmctl(shmid,IPC_STAT,&buf);

printf(\"size of the share memory:shm_segsz=%dbytes\\n\

printf(\"process id of the last operator:shm_lpid=%d\\n\

printf(\"process id of the last operator:shm_lpid+%d\\n\

shmaddr=(char *)shmat(shmid,NULL,0);

if(shmaddr==(void *)-1)

{

printf(\"connectthe share memory failed:%s\

return 0;

}

printf(\"print the content of the share memory:\");

printf(\"%s\\n\

shmdt(shmaddr);

shmctl(shmid,IPC_RMID,NULL);

}

}

4.2 shmget()调用

首先调用shmget()函数建立一块共享内存,大小为1024个字节,shmid=shmget(KEY,SIZE,IPC_CREAT | 0600)建立共享内存,此函数调用用于创建一个新的共享内存段或存取一个已存在的共享内存段 。 函数调用成功返回共享内存段的标识符 ,否则返回一 1值。s h mg e t的内部实现包含了许多重要的S y s t e m V共享内存机制;s h ma t 在把共享内存区域映射到进程空间时 , 并不真正改变进程的页表 。 当进程第一次访 问内存映射区域访问时, 会 因为没有物理页表 的分配而导致一个缺页异常, 然后 内核再根据相应 的存储管理机制为共享内存映射区域分配相应的页表。

4.3 fork()的调用

调用fork()产生一个子进程(生产者进程)。子进程调用shmat()函数将该共享内存连接(attach)到自己的虚存空间,即可通过普通的内存写操作(例如strcpy等),在该共享内存写入数据。

4.4 子进程调用shmat()

shmaddr=(char *)shmat(shmid,NULL,0) 系统自动选择一个地址连接,s h ma t ( ) 可以创建一个共享内存区,或者获得已创建的共享内存区的标识符后,将共享内存段映射到进程的内存空间。返回共享内存段的地址, 否则返 回一 1值。

4.5子进程调用shmdt()

写完数据生,子进程调用shmdt(shmaddr)断开共享,此函数调用可以将映射到进程

的共享内存段撤消。函数调用成功返回0值, 否则返回一 1 。一个共享内存与一个进程分离时 .共享内存段的s h m a r r a y结构中的共享计数减 1 ,直至计数为 0 ,系统才真正删除这个共亨内存页面。

4.6 父进程调用 shmctl()

父进程sleep,直到子进程完成上述操作。shmctl(shmid,IPC_RMID,NULL)取得共享内存的相关信息,并打印出来s h mct l 可以用来查询一些共享内存的使用情况和进行一些控制操作。 函数调用成功后返回0值, 否则返回一 1 值。比如: s h mc t l ( s h m i d , I P C RMI D, 0 ) 将删除s h m i d指示的共享内存。

4.7父进程调用shmat(),shmdt(),shmctl()

父进程调用shmat()函数将这块共享内存连接到自己的虚存空间,即可通过普通的内存读操作(例如printft等),将该共享内存中的字符串读出来。

读完数据后,父进程调用shmctl()函数,销毁断开与该共享内存的连接。

最后父进程调用shmectl()函数,销毁该共享内存。

五、实验的调试与测试

代码编辑如下图所示

在linux操作系统下,打开终端,使用vi工具编写代码

编写如下图5-1,图5-2,图5-3代码

图5-1

图5-2

图5-3

使用gcc –o share share.c编译代码

六、实验结果

运行./share 结果如下图

七、源程序

#include

#include

#include

#include

#include

#include

#define KEY 1234

#define SIZE 1024

int main()

{

int shmid;

char *shmaddr;

struct shmid_ds buf;

shmid=shmget(KEY,SIZE,IPC_CREAT | 0600);

if(shmid==-1)

{

printf(\"create share memory failed:%s\

return 0;

}

if(fork()==0)

{

sleep(2);

shmaddr=(char *)shmat(shmid,NULL,0);

if(shmaddr==(void*)-1)

{

printf(\"connect to the share memory failed:%s\

return 0;

}

strcpy(shmaddr,\"hello,this is shared data.\\n\");

shmdt(shmaddr);

exit(0);

}else

{

wait(0);

shmctl(shmid,IPC_STAT,&buf);

printf(\"size of the share

memory:shm_segsz=%dbytes\\n\

printf(\"process id operator:shm_lpid=%d\\n\

printf(\"process id operator:shm_lpid+%d\\n\

shmaddr=(char *)shmat(shmid,NULL,0);

if(shmaddr==(void *)-1)

{

printf(\"connect the share memory failed:%s\

return 0;

}

printf(\"print the content of the share memory:\");

printf(\"%s\\n\

of the of the last last

shmdt(shmaddr);

shmctl(shmid,IPC_RMID,NULL);

}

}

八、实验感受

通过本次实验,我明白了父进程与子进程的共享原理,同时我还明白了如何实现父进程程子进程通过共享实现信息的交换,通过对试验的操作,我们对课本上的知识得到了巩固和提高,对进程通信和内存共享等功能有了较全面的理解。这次课程实践充分锻炼了我的动手能力,思维能力,设计能力,在这次课程实践中,我主动查询资料,询问同学。通过本次的课程实践,我对共享内存有关的知识有了进一步的了解,刚刚开始我并不知道如何去完成这次的课程实践,但通过我去网上查询有关的资料,我最终知道该从哪里下手去写这篇课程实践。通过本次的课程实践,我知道了自己身上的不足和自己知识的欠缺。本次课程实践,我不断地在linux系统中调试代码,花了较多的时间,最终成功的把代码调试好,心中充满着喜愉,通过本课程实践,我增加了许多的知识,对共享内存的原理,我比以前有了更进一步的了解。在本次的课程实践中,在调试代码过程中,我发现有较多的错误,这些错误的产生都是因为我对知识的认识不够深入而产生的。

九、参考文献

1、汤小丹,梁红兵编著·《计算机操作系统》(第三版)·西安电子科技大学出版社,2007

2、张尧学,史美林,张高编著·《计算机操作系统教程》(第3版)·清华大学出版社,2006

3、、严蔚敏,吴伟民编著·《数据结构》(C语言版)·清华大学出版社,2007

4、《计算机操作系统(修订版)》汤子瀛 西安电子科技大学出版社

5、《操作系统考研辅导教程(计算机专业研究生入学考试全真题解) 》电子科技大学出版社

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- yule263.com 版权所有 湘ICP备2023023988号-1

违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务