1、实验六 进程间通信共享存储区的创建、附接和断接实验目的了解和熟悉共享存储机制实验内容编制一长度为 1k 的共享存储区发送和接收的程序。程序设计(1) 为了便于操作和观察结果,用一个程序作为“引子” ,先后fork()两个子进程, SERVER 和 CLIENT,进行通信。(2) SERVER 端建立一个 key 为 75 的共享区,并将第一个字节设置为-1,。作为数据空的标志。等待其他进程发来的消息。当字节的值发生变化时,表示收到了信息,进行处理。然后再次把它的值设为-1。如果遇到的值为 0,则视为结束信号,取消该队列,并退出 SERVER。SERVER 每接收到一个数据后显示“(server
2、)receive”。(3) CLIENT 端建立一个 key 为 75 的共享区,当共享取得第一个字节为-1 时,Server 端空闲,可发送请求。CLIENT 随即填入9 到 0。期间等待 server 端的再次空闲。进行完这些操作后,CLIENT 退出。CLIENT 每发出一次数据后显示 “(client )sent”。(4) 父进程在 SERVER 和 CLIENT 均退出后结束。实验指导一、共享存储区1、共享存储区机制的概念共享存储区(Share Memory)是 UNIX 系统中通信速度最高的一种通信机制。该机制可使若干进程共享主存中的某一个区域,且使该区域出现(映射)在多个进程的虚
3、地址空间中。另一方面,一个进程的虚地址空间中又可连接多个共享存储区,每个共享存储区都有自己的名字。当进程间欲利用共享存储区进行通信时,必须先在主存中建立一共享存储区,然后将它附接到自己的虚地址空间上。此后,进程对该区的访问操作,与对其虚地址空间的其它部分的操作完全相同。进程之间便可通过对共享存储区中数据的读、写来进行直接通信。图示列出二个进程通过共享一个共享存储区来进行通信的例子。其中,进程 A 将建立的共享存储区附接到自己的AA区域,进程 B 将它附接到自己的 BB区进程 A 的虚空间 内存空间 进程 B 的虚空间AA应当指出,共享存储区机制只为进程提供了用于实现通信的共享存储区和对共享存储
4、区进行操作的手段,然而并未提供对该区进行互斥访问及进程同步的措施。因而当用户需要使用该机制时,必须自己设置同步和互斥措施才能保证实现正确的通信。二、涉及的系统调用1、shmget( )创建、获得一个共享存储区。系统调用格式:shmid=shmget(key,size,flag)该函数使用头文件如下:#include#include#include参数定义int shmget(key,size,flag);key_t key;int size,flag;其中,key 是共享存储区的名字; size 是其大小(以字节计) ;flag 是用户设置的标志,如 IPC_CREAT。 IPC_CREAT
5、表示若系统中尚无指名的共享存储区,则由核心建立一个共享存储区;若系统中已有共享存储区,便忽略 IPC_CREAT。附:操作允许权 八进制数用户可读 00400正文数据栈共享存储区正文数据BB栈用户可写 00200小组可读 00040小组可写 00020 其它可读 00004其它可写 00002控制命令 值IPC_CREAT 0001000IPC_EXCL 0002000例:shmid=shmget(key,size,(IPC_CREAT|0400)创建一个关键字为 key,长度为 size 的共享存储区2、shmat( )共享存储区的附接。从逻辑上将一个共享存储区附接到进程的虚拟地址空间上。系
6、统调用格式:virtaddr=shmat(shmid,addr,flag)该函数使用头文件如下:#include#include#include参数定义char *shmat(shmid,addr,flag);int shmid,flag;char * addr;其中,shmid 是共享存储区的标识符;addr 是用户给定的,将共享存储区附接到进程的虚地址空间;flag 规定共享存储区的读、写权限,以及系统是否应对用户规定的地址做舍入操作。其值为SHM_RDONLY 时,表示只能读;其值为 0 时,表示可读、可写;其值为 SHM_RND(取整)时,表示操作系统在必要时舍去这个地址。该系统调用的
7、返回值是共享存储区所附接到的进程虚地址viraddr。3、shmdt( )把一个共享存储区从指定进程的虚地址空间断开。系统调用格式:shmdt(addr)该函数使用头文件如下:#include#include#include参数定义int shmdt(addr);char addr;其中,addr 是要断开连接的虚地址,亦即以前由连接的系统调用 shmat( )所返回的虚地址。调用成功时,返回 0 值,调用不成功,返回-1 。4、shmctl( )共享存储区的控制,对其状态信息进行读取和修改。系统调用格式:shmctl(shmid,cmd,buf)该函数使用头文件如下:#include#inc
8、lude#include参数定义int shmctl(shmid,cmd,buf);int shmid,cmd;struct shmid_ds *buf;其中,buf 是用户缓冲区地址,cmd 是操作命令。命令可分为多种类型:(1)用于查询有关共享存储区的情况。如其长度、当前连接的进程数、共享区的创建者标识符等;(2)用于设置或改变共享存储区的属性。如共享存储区的许可权、当前连接的进程计数等;(3)对共享存储区的加锁和解锁命令;(4)删除共享存储区标识符等。上述的查询是将 shmid 所指示的数据结构中的有关成员,放入所指示的缓冲区中;而设置是用由 buf 所指示的缓冲区内容来设置由 shmid 所指示的数据结构中的相应成员。