自己做网站 需要哪些,大连网站建设开发,网站制作学费多少钱,做微商货源网站赚钱吗进程的共享主存通信 【预备知识】 共享存储区为进程提供了直接通过主存进行通信的有效手段#xff0c;不像消息缓冲机制那样需要系统提供缓冲#xff0c;也不像pipe机制那样需要事先建立一个特殊文件#xff0c;而是由通信双方直接访问某些共享虚拟储存空间。在Linux中… 进程的共享主存通信 【预备知识】 共享存储区为进程提供了直接通过主存进行通信的有效手段不像消息缓冲机制那样需要系统提供缓冲也不像pipe机制那样需要事先建立一个特殊文件而是由通信双方直接访问某些共享虚拟储存空间。在Linux中系统管理一组共享主存段控制块。通信进程在使用共享主存段以前首先提出申请系统为之分配存储空间并返回共享主存段标识号。一个共享段建立后进程把它被附加到自己虚拟空间中。一个进程可以附加多个共享主存段。一个共享主存段一旦被附加到进程的虚拟空间后对它的访问与其他虚拟地址的访问完全相同。但为了保证共享主存段数据的完整性通信的进程之间要互斥地进行访问。当通信进程不再需要该共享主存段时可使用命令将其与进程分离从而使其从进程的虚空间删除。 共享主存段使用的数据结构 (1)共享主存段控制块或共享主存段头 每个共享主存段都有一个控制块用来描述共享主存段的一些属性共享主存段控制块定义在sys/shm.h中其结构如下 struct shmid_ds { struct ipc_perm shmperm; / * 共享主存段访问控制结构 * / int shmsegsz; / * 共享段以字节为单位的长度 * / struct ptentry * shmptbl; / * 共享页表始址 * / ushort shmlpid; / * 最近执行共享段操作的进程标识 * / ushort shmcpid; / * 创建共享段的进程标识 * / ushort shmnattch; / * 当前附件段号 * / ushort shmcnattch; / * 主存中的附加段号 * / time_t shmatime; / * 最近一次附件操作的时间 * / time_t shmdtime; / * 最近一次与进程分离操作的时间 * / time_t shmctime; / * 最近一次修改时间 * / } 为了便于管理系统将维持的共享主存段组成一个表共有SHMMNI100个元素其结构如下 struct shmid_ds shmen[SHMMNI]; / * 共享段表 * / 其访问控制结构定义如下 struct ipc_perm key_t key; ushort uid; /* owner euid and egid * / ushort gid; ushort cuid; ushort cgid; ushort mode; /*lower 9 bits of shmflg*/ ushort seq /*sequence number*/ }; (2)共享主存段的数据结构 每个共享主存段都对应一个页表和允许的存取权限结构如下 struct shmptds { int shmspte; /*开始也表项*/ int shmsflg; /*对共享段的读/写权限*/ } 每个进程最多允许6个共享主存段SHMSEG6). 申请一个共享主存段 参与通信的进程通信前要先申请一个共享主存段若是第一次申请则要为其分配一个主存空间及页表并对共享主存区控制块进行初始化申请共享主存段调用语法如下 # includesys/ipc.h # includesys/shm.h int shmget(key_t key,size_t size,int shmflg) 其中key为共享主存段的关键字size是共享主存段字节长度shmflg为创建和访问标志。 返回值成功时为与key值相关的共享主存段的标识号且大小是页对齐失败时为-1。 如果key的值为IPC_PRIVATE,或不为IPC_PRIVATE创建的共享段与key无关关键字由系统分配。 Shmflg由如下成分组成 .IPC_CREAT创建一个新段。如果该标志没有设置将查找与key相关的段且该段允许用户访问。 .IPC_EXCL与IPC_CREAT一起使用确保创建一个新的共享段。若该段已经存在出错。 低9位为三类用户的访问方式的定义。 将共享段附加到申请通信的进程空间 对于已申请通信所需的共享段进程需把它附加到自己的虚拟空间后才能对其进行读写将共享段附加到申请通信的进程空间的函数调用语法 #include sys/sem.h void shmat ( int shmidcoid * shmaddnt shmflg) 这里shmid是进程调用shmget后返回的共享段标识号shmadd是给出的应附加到进程虚空间的地址shmflg为允许对共享段的访问方式。 返回值成功时为附加到进程地址空间的虚地址失败时为-1。 连接到进程虚空间的地址规则为 .shmadd为0则将该共享段附加到系统选择的进程的第一个可用地址之后。 .shmadd为非0如果shmflg指定了SHM_RND标志则将该共享段附加shmadd取整后指定的地址上。 .shmadd为非0如果shmflg未指定SHM_RND标志则将该共享段附加shmadd指定的地址上。通常将shmadd指定为0由系统安排连接地址。 4.将共享段与进程之间解除链接 当进程不再需要共享段时将其从它的地址空间拆下调用语法为 #include sys/sem.h int shmdt( void * shmaddr ) 其中shmaddr是共享段在进程地址空间的虚地址。返回值为0。 5.对共享段进行控制 #include sys/sem.h int shmctlint shmidint cmdstruct_ds * buf 返回值成功时为0失败时为-1。 系统调用shmctl根据控制命令cmd对共享段进行控制。cmd可能的取值有 . IPC_STAT将有关共享段的信息复制到具有shmid_ds结构的buf中 . IPC_SET用于用户和用户组或对其存取权限进行修改要求用户必须为超级用户或拥有者 . IPC_RMID用于标志删除共享段。在共享段与所有进行分离时实际进行删除 . IPC_LOCK在Linux环境下将共享段锁在主存中 . IPC_UNLOCK在Linux环境下允许将共享段锁换出主存。 编程实现例一 【任务】 编程实现一个是进程向共享段写信息的例子。 【程序】 #include sys/types.h#include sys/ipc.h#include sys/shm.h#define SHMKEY 75#define K 1024int shmid;main(){int i,*pint;char *addr;extern char *shmat();shmidshmget(SHMKEY,16*K,0777|IPC_CREAT);/*申请创建一个16K大小的共享存储段其标识号为SHMKEY*/addrshmat(shmid,0,0); /*缺省地址将共享段附加到系统指定位置*/printf(“addr ox%x\n”,addr);/*打印附加到进程地址空间的地址*/pint(int *) addr;for (i0;i256;i)*pinti; /*向共享主存段写入0~255个数*/pint(int *)addr;*pint256; /*共享段第一个字中写入信息长度256以便接收进程读*/Pause(); /*暂停等待接收进程读*/} 修正后的代码 【运行结果】 【分析】 第一个例子是一个进程向共享段写信息的例子它使用了共享内存来实现进程间的通信。程序首先申请创建一个16K大小的共享存储段标识号为SHMKEY然后将共享段附加到系统指定位置并打印附加到进程地址空间的地址。接着向共享主存段写入0~255个数并在共享段第一个字中写入信息长度256以便接收进程读取。最后暂停等待接收进程读 编程实现例二 【任务】 编程实现从共享段读信息的例子 【程序】 #include sys/types.h#include sys/ipc.h#include sys/shm.h#define SHMKEY 75#define K 1024int shmid;main(){int i,*pint;char *addr;extern char *shmat();shmidshmget(SHMKEY,8*K,0777); /*由SHMKEY得到共享段标识号*/addrshmat(shmid,0,0); /*将共享段与本进程相连*/pint(int *) addr;while (*pint0); /*若共享区无信息时在此等待*/for (i0;i256;i)printf(“%d\n”,*pint);} 修正后的代码 【运行结果】 【分析】 第二个例子是一个从共享段读信息的例子同样使用了共享内存来实现进程间的通信。程序首先通过SHMKEY得到共享段标识号然后将共享段与本进程相连。接着程序进入一个while循环在共享区无信息时在此等待。当共享区有信息时将信息读取出来并打印出来。