共享存储区(Share Memory)是Linux系统中通讯速度最高的通讯机制。该机制中共享内存空间和进程的虚地址空间知足多对多的关系。即一个共享内存空间能够映射多个进程的虚地址空间,一个进程的虚地址空间又能够链接多个共享存储区。当进程间预利用共享存储区通讯时,先要在主存中创建一个共享存储区,而后将它附接到本身的虚地址空间。该机制只为进程提供了用于实现通讯的共享存储区和对共享存储区进行操做的手段,然而并未提供对该区进行互斥访问及进程同步的措施。linux
shmget(key ,size ,flag)数组
功能:得到一个内部标识为shmid的共享存储区。数据结构
语法:int shmget = int shmget(key_t key ,int size ,int flag);函数
参数说明:操作系统
key 共享存储区关键字,可由用户指定。若使用IPC_PRIVATE则其值由系统产生。3d
size 存储区大小(字节数)。若存储区定义为字符型,则大小为定义的字符个数;若定义为整型,大小能够用sizeof(int)加以定义code
flag 用户设置的标志或访问方式,如0666|IPC_CREAT,表示任意进程皆可读可写blog
操做容许权 | 八进制数 | 操做容许权 | 八进制数 |
---|---|---|---|
用户可读 | 0400 | 小组可写 | 0020 |
用户可写 | 0200 | 其它可读 | 0004 |
小组可读 | 0040 | 其它可写 | 0002 |
字符型共享内存:进程
shmat(int shmid ,char shmadddr ,int msgflg ,ulong raddr);内存
数值型共享内存:
shmat(int shmid ,int shmadddr ,int msgflg ,ulong raddr);
语法格式:
字符型共享内存:
viraddr = (char *) shmat (shmid ,shmaddr ,shmflag);
viraddr = (int *) shmat (shmid ,shmaddr ,shmflag);
参数说明:
shmid共享存储区的描述符,可由shmget()的返回值获得。
shmaddr用户提供的共享存储区附接的虚地址。
shmflag规定存储区的操做权限。如,SHM_RND则表示操做系统在必要时舍去地址;SHM_RDONLY则表示只容许读,shmflag为0表示可读可写。
shmdt(viraddr)
参数说明:
viraddr系统调用shmat()所返回的虚地址。
返回值:
函数被正确调用则返回0,错误返回-1
shmctl(int shmid ,int cmd ,struct shmid_ds * buf);
功能:对共享内存进行操做控制
参数说明:
shmid共享存储区的描述符,可由shmget()的返回值获得。
buf用户级数据结构地址,可为0。
cmd规定的操做类型
操做代码 | 含义 |
---|---|
IPC_STAT | 返回指定shmid数据结构的状态信息,放置于*buf中,必须有读取容许权 |
IPC_SET | 设置指定shmid的有效用户和操做存取权 |
IPC_RMID | 删除指定shmid以及与它相关的共享存储区的数据结构 |
SHM_LOCK | 在内存中锁定指定的共享存储区,必须是root才能执行 |
shmctl(shmid ,IPC_RMID ,0); //撤销共享内存区
send:
receive:
send
#include<stdio.h> #include<stdlib.h> #include<string.h> #include<unistd.h> #include<sys/types.h> #include<sys/shm.h> /*共享内存 share memory 实现的进程通讯*/ main() { int shmid; char *viraddr; char buffer[BUFSIZ]; shmid=shmget(1234,BUFSIZ,0666|IPC_CREAT); viraddr=(char*)shmat(shmid,0,0); while(1) { puts("Enter some text:"); fgets(buffer,BUFSIZ,stdin);/*从标准输入设备读入一行字符串,stdin是标准输入,C标准库里面的一 个全局变量*/ strcat(viraddr,buffer); /*字符串追加函数*/ if(strncmp(buffer,"end",3)==0)/*比较两个字符串数组*/ break; } shmdt(viraddr); exit(0); }
receive
#include<stdio.h> #include<stdlib.h> #include<string.h> #include<unistd.h> #include<sys/types.h> #include<sys/shm.h> main() { int shmid; char *viraddr; shmid=shmget(1234,BUFSIZ,0666|IPC_CREAT); viraddr=(char*)shmat(shmid,0,0); printf("Your message is :\n%s",viraddr); shmdt(viraddr); /*断开链接*/ shmctl(shmid,IPC_RMID,0); /*撤销共享内存*/ exit(0); }
运行结果
#include<stdio.h> #include<stdlib.h> #include<string.h> #include<unistd.h> #include<sys/types.h> #include<sys/shm.h> /* 父进程与子进程间的通讯,子进程写信息到共享内存中,父进程读取该信息 BUFSIZ为全局量定义在<stdlib.h>,8192 使用exit(0)和wait(0)进行同步*/ main() { int chld,shmid; char *viraddr; char buffer[BUFSIZ]; shmid=shmget(IPC_PRIVATE,BUFSIZ,0666|IPC_CREAT); viraddr=(char*)shmat(shmid,0,0); while((chld=fork())==-1); if(chld==0) { /*子进程块*/ while(1) { puts("Enter some text:"); /*写信息到共享内存*/ fgets(buffer,BUFSIZ,stdin); /*用户输入信息*/ strcat(viraddr,buffer); /*附接到进程的虚拟空间*/ if(strncmp(buffer,"end",3)==0) break; /*输入end结束*/ } exit(0); } else { /*父进程块*/ wait(0); printf("Your message is:\n%s",viraddr); shmdt(viraddr); /*断开共享内存*/ shmctl(shmid,IPC_RMID,0); /*释放共享内存*/ exit(0); } }
运行结果