作者:小 琛
欢迎转载,请标明出处
共享内存原理与特性
原理:创建共享内存的时候,则在物理内存中开辟一段空间,各个进程通过自己的页表结构,将物理空间映射到自己的虚拟地址空间上的共享区,各个进程通过操作自己的虚拟内存上面的共享区来进行通信。
特性:
- 共享内存是最快的进程间通信方式
- 共享内存是不带有同步和互斥功能的
- 写入数据是按照覆盖的方式进行的
- 生命周期跟随操作系统内核
接口函数
int shmget(key_t key,size_t size,int shmflg)
- 功能:创建共享内存
- 参数
key:共享内存的标识符,可自己设定
size:共享内存的大小
shmflg:
- IPC_CREAT:如果打开的共享内存不存在则创建,若存在,返回该内存
- IPC_CREAT|IPC_EXCL:如果打开的共享内存存在,则报错;如果不存在,则创建。可以在后面按位或权限
- 返回值
成功返回共享内存的操作句柄。
void* shmat(int shmid,const void* shmaddr,int shmflg)
- 功能:将共享内存附加到进程
- 参数
shmid:共享内存的操作句柄
shmaddr:映射到共享区的哪一个地址,通常穿NULL,由操作系统分配
shmflg:
- 0:可读可写
- IPC_RDONLY:只读
- 返回值
返回映射到共享区的一个地址
int shmdt(const void* shmaddr)
- 功能:分离共享区和进程
- 参数
shmaddr:映射到共享区当中内存的首地址
int shmctl(int shmid,int cmd,struct shmid_ds* buf)
- 功能:共享内存的控制
- 参数
- shmid:共享内存的操作句柄 cmd:想让该函数做什么操作
- cmd:想让该函数做什么操作。
IPC_STAT:获取共享内存状态。 IPC_RMID:删除共享内存- buf:保存共享内存信息的一个结构体,配合IPC_STAT作为出参
通信例子
shmwrite.c
1 #include "stdio.h"
2 #include "unistd.h"
3 #include "sys/shm.h"
4 #define shmkey 0x99999999
5
6 int main()
7 {
8 int shmid=shmget(shmkey,1024,IPC_CREAT|0664);
9 if (shmid < 0)
10 {
11 perror("shmget");
12 return 0;
13 }
14 void* adder=shmat(shmid,NULL,0);
15 if (!adder)
16 {
17 perror("shmat");
18 return 0;
19 }
20 int i=0;
21 while (1)
22 {
23 fflush(NULL);
24 sprintf((char*)adder,"%s -%d","xiao chen",i);
25 printf("%s - %d\n","xiao chen",i);
26 i++;
27 sleep(2);
28 }
29 shmdt(adder);
30 shmctl(shmid,IPC_RMID,NULL);
31 return 0;
32 }
shmread.c
1 #include "stdio.h"
2 #include "unistd.h"
3 #include "sys/shm.h"
4
5 #define shmkey 0x99999999
6
7 int main()
8 {
9 int shmid=shmget(shmkey,1024,IPC_CREAT|0664);
10 printf("1\n");
11 if (shmid < 0)
12 {
13 perror("shmget");
14 return 0;
15 }
16 struct shmid_ds buff;
17 shmctl(shmid,IPC_STAT,&buff);
18 printf("shm size =%ld\n",buff.shm_segsz);
19
20 void* adder=shmat(shmid,NULL,0);
21 if (!adder)
22 {
23 perror("shmat");
24 return 0;
25 }
26 while (1)
27 {
28 fflush(NULL);
29 printf("i read [%s]\n",(char*)adder);
30 sleep(2);
31 }
32 shmdt(adder);
33 shmctl(shmid,IPC_RMID,NULL);
34 return 0;
35 }
结果