概念
共享内存可以通过mmap映射普通文件
使一个磁盘文件与内存中的一个缓冲区相映射进程可以像访问普通内存一样对文件进行访问不必再调用read,write。
优点
实现用户空间和内核空间的高效交互方式
注意事项:
1.创建映射区的过程中,隐含着一次对映射文件的读操作,将文件内容读取到映射区。
2.当 MAP SHARED 时,要求: 映射区的权限应 =文件打开的权限(出于对映射区的保护),如果不满足报非法参数 (Invalid argument) 错误。
3.当MAP_PRIVATE 时候,mmap 中的权限是对内存的限制,只需要文件有读权限即可,操作只在内存有效,不会写到物理磁盘,且不能在进程间共享
4.映射区的释放与文件关闭无关,只要映射建立成功,文件可以立即关闭。
5.用于映射的文件大小必须>0,当映射文件大小为 0 时,指定非 大小创建映射区,访问映射地址会报总线错误,指定 0 大小创建映射区,报非法参数错误 (Invalid argument)
6.文件偏移量必须为0或者 4K 的整数倍(不是会报非法参数 nvalid argument 错误)
7.映射大小可以大于文件大小,但只能访问文件 page 的内存地址,否则报总线错误超出映射的内存大小报段错误
mmap()映射的种类
基于文件的映射
匿名映射:适用于具有亲缘关系的进程之间
#include <string.h>
#include <sys/types.h>
#include <fcntl.h>
int main(){
void *addr;
int fd;
fd = open("test",O_RDWR);
if(fd<0){
perror("open");
return 0;
}
int len = lseek(fd,0,SEEK_END);
addr = mmap(NULL,100,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);
if(addr == MAP_FAILED)
{
perror("mmap");
return 0;
}
memcpy (addr,"abcdefg",7);
printf("read=%s\n",(char*)addr);
}
释放:munmap
共享内存通信
#include <string.h>
#include <sys/types.h>
#include <fcntl.h>
int main(){
void *addr;
int fd;
fd = open("test",O_RDWR);
if(fd<0){
perror("open");
return 0;
}
int len = lseek(fd,0,SEEK_END);
addr = mmap(NULL,2048,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);
if(addr == MAP_FAILED)
{
perror("mmap");
return 0;
}
//写
memcpy (addr,"abcdefg",7);
//读
printf("read=%s\n",(char*)addr);
}
共享内存system V
共享内存使用步骤:
1.生成key
2.创建/打开共享内存
3.映射共享内存,即把指定的共享内存映射到进程的地址空间用于访问
4.读写共享内存
5.撤销共享内存映射
6.删除共享内存对象