Linux系统编程 共享内存 mmap

1.mmap函数介绍

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

返回:成功:返回创建的映射区首地址;失败:MAP_FAILED 宏
参数:

addr: 建设映射区的首地址,由Linux内核指定,使用时,直接传递NULL
length:欲创建映射区的大小
prot:映射区权限 PROT_READ、PROT_WRITE、PROT_READ | PROT_WAITE (读写)
flags: 标志位参数 (常用于设定更新物理区域、设置共享、创建匿名映射区)
MAP_SHARED: 会将映射区所做的操作反映到物理设备(磁盘)上
MAP_PRIVATE: 映射区所做的修改不会反映到物理设备
fd: 用来建立映射区的文件描述符
offset: 映射文件的偏移(4k 的整数倍) (映射一部分)

2.mmap实践

1.打开一个文件(或者穿件一个新文件),
2.用mmap函数,创建内存映射区(参数MAP_SHARED,会反映到映射区)
3.通过指针p,向内存映射区写入数据
4.关闭映射区,关闭文件

#include<stdio.h>
#include<fcntl.h>
#include<unistd.h>
#include<string.h>
#include<stdlib.h>
#include<sys/mman.h>

int main()
{         
        int len, ret;
        char *p = NULL;
        int fd = open("mytest.txt",O_CREAT|O_RDWR,0644);//打开文件
        if(fd < 0){ 
                perror("open error:");
                exit(1);
        }
        len = ftruncate(fd,4);
        if( len == -1 ){        
                perror("ftruncate error:");
                exit(1);
        } 
        //泛型指针可以和任意的指针类型,完成隐式转换
        p = mmap(NULL, 4, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);//创建映射区
        if (p == MAP_FAILED){   
                perror("mmap error:");
                exit(1);
        }
        strcpy(p , "abc"); //模拟p指针向内存写数据
        ret = munmap(p, 4);
        if(ret == -1){
                perror("munmap error:");
                exit(1);
        }

        close(fd);//关闭文件

        return 0;
}
         

5.结果,是mytest.txt文件中,有写入的数据 “abc”
在这里插入图片描述

3.mmap相关问题

0.可以open的时候 O_CREAT一个新文件来创建映射区吗?
可以,上面的代码就是以 O_CREAT 一个新文件来创建映射区的。
1.可不可以创建大小为0的映射区呢?不可以
在这里插入图片描述
在这里插入图片描述

2.如果p++ ,munmap可否成功?

在这里插入图片描述
在这里插入图片描述
不能成功,因为munmap 回收时,要传入映射区的首地址

3.如果open时O_RDONLY,mmap时PROT参数指定PROT_READ | PROT_WRITE 会怎样?

不行,权限不够,映射区无写权限。
在这里插入图片描述在这里插入图片描述

若mmap函数flags参数修改为 MAP_PRIVATE,会出现总线错误,由于硬件异常导致的,和实际空间大小和访问权限有关。
在这里插入图片描述

若mmap函数flags参数修改为 MAP_SHARED,以只写方式打开文件,以只写方式创建映射区。

在这里插入图片描述
在这里插入图片描述

若都修改为只读
在这里插入图片描述
在这里插入图片描述

结论:1.创建映射区的权限,小于等于文件打开的权限
2.创建映射区的过程,隐含着对文件的读操作

3.如果文件偏移量为1000会怎样?

不行,必须是4k的整数倍(一页的大小)。映射区是MMU帮助完成映射,所以为4k的倍数

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值