一.优点
共享内存是最快的IPC
二.本质
同一个物理内存同时映射到不同进程的虚拟地址空间中,共享内存其实是效率最高的通信方式,访问共享内存和访问其他内存没有什么区别。
三.特性
1)可用于任何进程之间
2)双向通信,全双工
3)没有内置同步互斥机制
4)支持随机访问
5)没有内置同步互斥机制
6)声明周期随内核
四.API
1.创建和打开共享内存
1)头文件: #include <sys/ipc.h>
#include <sys/shm.h>
2)函数原型:int shmget(key_t key, size_t size, int shmflg);
3)函数参数:key 共享内存的名字 size 共享内存的大小 shmflg 由九个权限标志构成,用法和创建文件时的mode一样
4)返回值:成功返回共享内存的标识码,失败返回-1
5)特点:内存只分配4k的倍数,小于4k按4k分配
2.将共享内存挂载到进程的地址空间
1)头文件:#include <sys/types.h>
#include <sys/shm.h>
2)函数原型:void *shmat(int shmid, const void *shmaddr, int shmflg);
3)函数参数:shmid 共享内存标识码 shmaddr 指定连接的地址(为NULL操作系统自己选择)
shmflg 两个值SHM_RND和SHM_RDONLY
4)返回值:成功返回挂载到虚拟空间起始地址的指针,失败返回-1
5)说明:shmaddr不为空,shmflg无SHM_RND标记,则以shmaddr为连接地址
shmaddr不为空,shmflg有SHM_RND标记,则连接的地址会自动向下调整为SHMLBA的整数倍
shmflg=SHM_RDONLY,表示连接操作用来只读共享内存
3.将共享内存与当前进程脱离
1)头文件:#include <sys/types.h>
#include <sys/shm.h>
2)函数原型:int shmdt(const void *shmaddr);
3)参数:shmaddr:由shmat所返回的指针
4)返回值:成功返回0,失败返回-1
5)注意:脱离只是从进程上卸载,并不等于删除共享内存
4.控制共享内存
1)头文件:#include <sys/ipc.h>
#include <sys/shm.h>
2)函数原型:int shmctl(int shmid, int cmd, struct shmid_ds *buf);
3)函数参数:shmid 共享内存标识码 cmd 将要采取的动作 buf 指向一个保存着共享内存的模式状态和访问权限的数据结构
4)返回值:成功返回0,失败返回-1
5)说明:cmd的三种情况 IPC_STAT把shmid_ds结构中的数据设置为共享内存的当前关联值
IPC_SET 在进程有足够权限的前提下,把共享内存的当前关联值设置为shmid_ds数据结构中给出的值
IPC_RMID删除共享内存段
五.撸一段代码
sever
1 #include <stdio.h>
2 #include <sys/ipc.h>
3 #include <sys/shm.h>
4 #include <sys/types.h>
5
6 int main(void){
7 key_t key=ftok(".",0x001);
8 int shm=shmget(key,4096,IPC_CREAT|0644);
9 if(shm<0){
10 perror("shmget");
11 return 1;
12 }
13
14 char* point=shmat(shm,NULL,0);
15 if(point==NULL){
16 perror("shmat");
17 return 1;
18 }
19 while(1){
20 printf("me say:");
21 fflush(stdout);
22 scanf("%s",point);
23 if(strcmp(point,"exit")==0){
24 break;
25 }
26
27 printf("Other say:");
28 fflush(stdout);
29 sleep(3);
30 printf("%s\n",point);
31 }
32 shmctl(shm,IPC_RMID,0);
33 return 0;
34
35 }
client
1 #include <stdio.h>
2 #include <sys/ipc.h>
3 #include <sys/shm.h>
4 #include <sys/types.h>
5
6 int main(void){
7 int key=ftok(".",0x001);
8 int shm=shmget(key,4096,0);
9 if(shm<0) perror("shmget"),exit(1);
10
11 char * buf;
12 buf=shmat(shm,NULL,0);
13 if(*buf==-1){
14 perror("shmat");
15 return 1;
16 }
17 while(1){
18 printf("Other say#");
19 fflush(stdout);
20 sleep(3);
21 printf("%s\n",buf);
22 buf=NULL;
23 printf("me say:");
24 fflush(stdout);
25 scanf("%s",buf);
26 }
27 return 0;
28 }
总结:由于共享内存没有同步互斥机制,在两方操作难度很大,很难进行互斥操作,在以后信号量的地方我会继续改进。