共享内存
共享内存是被多个进程共享的一部分物理内存。共享内存是进程间共享数据的一种最快的方法,一个进程向共享内存区域写入了数据,共享这个内存区域的所有进程就可以立刻看到其中的内容。原理图如下:
为什么要使用共享内存?
因为管道通信,每次都要调用系统IO,调用系统IO是很损耗系统资源的,假如有某些数据,进程之间是频繁访问的,我们就可以在系统中申请一片内存让他们共同访问。
实现共享内存的步骤:
1.创建共享内存对象 ---》shmget
2.映射共享内存空间 ---》shmat
3.解除映射空间---》shmdt
4.销毁共享内存---》shmctl
下面对三个函数的使用进行说明
1.创建对象shmget函数
头文件:
#include <sys/ipc.h>
#include <sys/shm.h>
函数原型:
int shmget(key_t key, size_t size, int shmflg);
参数一:秘钥,需要一个唯一的key
参数二:开辟共享内存的大小
参数三:权限
IPC_CREAT 创建,假如存在则打开
IPC_EXCL 检查
|0666
返回值:成功返回对象ID ,
失败返回-1
2.映射空间shmat函数
头文件:
#include <sys/types.h>
#include <sys/shm.h>
函数原型:
void *shmat(int shmid, const void *shmaddr, int shmflg);
参数一:共享内存对象ID
参数二:映射空间的地址 一般为NULL
参数三: SHM_RDONLY -》只读
0 -》读写
返回值:映射空间的首地址 ,
失败返回 (void *) -1
3.解除映射shmdt函数
头文件:
#include <sys/types.h>
#include <sys/shm.h>
函数原型:
int shmdt(const void *shmaddr);
参数一:映射空间的首地址
返回值:成功返回0 失败返回-1
-----------------------------------------------------------------------------------
练习:使用共享内存进行读写操作 -》对 void *地址操作即可
【shmwrite.c】
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdio.h>
#include <string.h>
int main()
{
//创建共享内存对象
int shmid=shmget(ftok("./",120),1024,IPC_CREAT|0666);
if(shmid<0)
{
perror("shmid fail:");
}
//映射共享内存空间
char *p=shmat(shmid,NULL,0);
if(p != (void *)-1)
{
printf("mat ok\n");
}
else
{
perror("mat fail\n");
}
//进行读写操作
strcpy(p,"123456");
}
【shmread.c】
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdio.h>
#include <string.h>
int main()
{
//创建共享内存对象
int shmid=shmget(ftok("./",120),1024,IPC_CREAT|0666);
if(shmid<0)
{
perror("shmid fail:");
}
//映射共享内存空间
char *p=shmat(shmid,NULL,0);
if(p != (void *)-1)
{
printf("mat ok\n");
}
else
{
perror("mat fail\n");
}
//进行读写操作
printf("p=%s\n",p);
//解除映射
int ret=shmdt(p);
if(ret != 0)
{
perror("mdtfail:");
}
//销毁共享内存
ret=shmctl(shmid,IPC_RMID,NULL);
if(ret != 0)
{
perror("IPC_RMID:");
}
}
-------------------------------------------------------------------------------------------