day12 共享内存(内存映射的使用、注意事项、进程间通信、systemV共享内存)

内存映射的基本使用

概念:

功能共享内存可以通过mmap()映射普通文件。

是一个磁盘文件与内存中的一个缓冲区相映射,进程可以像访问普通内存一样对文件进行访问,不必在调用read 、write。

mmap()的优点:

实现了用户空间和内核空间的高效交互方式;

为什么要用mmap():

 函数定义:

void *mmap(void *add,size_t length, int prot, int flags, int fd, off_t offset);

功能:创建共享内存映射;

函数返回值:成功返回创建的映射区首地址,失败返回MAP_FAILED(((void*) -1)),设置error值;

参数说明:

addr:指定要映射 的内存地址,一般设置为NULL 让操作系统选择合适的内存地址。

length:必须 > 0 。映射空间的字节数,它从被映射文件开头offset个字节开始算起。

prot:指定共享内存的访问权限。可取如下几个值:PROT_READ(可读), PROT_WRITE(可写), PROT_EXEC(可执行), PROT_NONE(不可访问)。

flags:有以下几个常值指定:MAP_SHARED(共享的)、MAP_PRIVATE(私有的)、MAP_FIXED(表示必须使用start参数作为开始地址,如果失败不进行修正),其中,MAP_SHARED,MAP_PRIVATE必选其一,而MAP_FIXED则不推荐使用。MAP_ANONYMOUS(匿名映射,用于血缘关系进程间通信)

fd:表示要映射 的文件句柄。如果匿名映射写-1;

offset:表示要映射文件的偏移量,一般设置为0表示从文件头部开始映射。

内存映射使用注意事项

1、创建映射区的过程中,隐含着一次对映射文件的读操作,将文件内容读取到映射区;

2、(1)当MAP_SHARED使,要求:引水河区的权限 <= 文件打开的权限(出于对应社区的保护),如果不满足会出现非法参数(invaild argument)错误。

       (2)当MAP_PRIVATE时候,mmap中的权限是对内存的限制,只需要文件有读权限即可,操作只在内存有效,不会写到物理磁盘,且不能在进程间共享。

3、映射区的释放与文件关闭无关,只要映射建立成功,文件可以立即关闭。

4、用于映射的文件大小必须 > 0,当映射文件大小为0时,指定非0大小创建映射区,访问映射地址会报总线错误,指定0大小创建映射区,报非法参数错误(Invalid argument)。

5、文件偏移量必须为0或者4k的整数倍(不是则会报非法参数(Invalid argument)错误)。

6、映射大小可以大于未文件大小,但只能访问文件page的内存地址,否则报总线错误,超出映射的内存大小报段错误。

 7、mmap创建映射区出错概率非常高,一定要检查返回值,确保映射区建立成功在进行后续操作。

内存映射实现进程问题

mmap()映射种类:

1、基于文件的映射;

2、匿名映射,适用于具有亲缘关系的进程之间;

释放内存映射:

munmap函数

int munmap(void *addr, size_t, length);

返回值:成功返回0,失败返回-1,并设置errno值。

函数参数:

addr:调用mmap函数成功返回的映射区首地址

length:映射区大小(即:mmap函数的第二个参数)

systemV共享内存

IPC 的key:

 ftok 函数

key_t frok(const char *path, int id);

其中参数path是指定的文件名,这个文件必须是存在的而且可以访问的。id是子序号,他是一个8bit的整数,及范围0 ~ 255 当函数执行成功,则会返回key_t键值,否则返回-1.在一班的Unix中,通常是将文件的索引节点取出,然后在前面加上子序号就得到key_t的值。

system V共享内存使用步骤:

1、创建 / 打开共享内存;

2、映射共享内容,即把指定的共享内存映射到进程的地址空间用于访问;

3、读写共享内容;

4、撤销共享内存映射;

5、删除共享内存对象;

查看共享内存命令ipcs

共享内存创建 - shmget

int shmget(key_t key, int size, int shmflg);

共享内存映射

void *shmat(int shmid, const void *shmaddr,int shmflg);

第二个参数一般写NULL,表示自动映射

第三参数一般写0,表示可读写

共享内存撤销

int shmdt(void *shmaddr);

 撤销后,内存地址不可在访问。

共享内存控制

int  shmctl(int shmid, int cmd, struct shmid_ds *buf);
shmctl(shmid, IPC_RMID, NULL);                      //删除共享内存
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值