C语言中mmap()函数的使用

mmap()函数的主要用途有三个:
1、将一个普通文件映射到内存中,通常在需要对文件进行频繁读写时使用,这样用内存读写取代I/O读写,以获得较高的性能;
2、将特殊文件进行匿名内存映射,可以为关联进程提供共享内存空间;

3、为无关联的进程提供共享内存空间,一般也是将一个普通文件映射到内存中。

头文件:

 #include <sys/mman.h>
原型:

void *mmap(void *start,size_t length,int prot,int flags,int fd,off_t offsize);
参数说明:

参数start:指向欲映射的内存起始地址,通常设为 NULL,代表让系统自动选定地址,映射成功后返回该地址。

参数length:代表将文件中多大的部分映射到内存。

参数prot:映射区域的保护方式。可以为以下几种方式的组合:
PROT_EXEC       映射区域可被执行
PROT_READ       映射区域可被读取
PROT_WRITE     映射区域可被写入
PROT_NONE      映射区域不能存取


参数flags:影响映射区域的各种特性。在调用mmap()时必须要指定MAP_SHARED 或MAP_PRIVATE。
MAP_FIXED                如果参数start所指的地址无法成功建立映射时,则放弃映射,不对地址做修正。通常不鼓励用此旗标。
MAP_SHARED          对映射区域的写入数据会复制回文件内,而且允许其他映射该文件的进程共享。
MAP_PRIVATE            对映射区域的写入操作会产生一个映射文件的复制,即私人的“写入时复制”(copy on write)对此区域作的任何修改都不会写回原来的文件内容。
MAP_ANONYMOUS  建立匿名映射。此时会忽略参数fd,不涉及文件,而且映射区域无法和其他进程共享。
MAP_DENYWRITE   只允许对映射区域的写入操作,其他对文件直接写入的操作将会被拒绝。
MAP_LOCKED          将映射区域锁定住,这表示该区域不会被置换(swap)。


参数fd:要映射到内存中的文件描述符。如果使用匿名内存映射时,即flags中设置了MAP_ANONYMOUS,fd设为-1。有些系统不支持匿名内存映射,则可以使用fopen打开/dev/zero文件,然后对该文件进行映射,可以同样达到匿名内存映射的效果。

参数offset:文件映射的偏移量,通常设置为0,代表从文件最前方开始对应,offset必须是分页大小的整数倍。

返回值:

若映射成功则返回映射区的内存起始地址,否则返回MAP_FAILED(-1),错误原因存于errno 中。


错误代码:

EBADF          参数fd 不是有效的文件描述词
EACCES       存取权限有误。如果是MAP_PRIVATE 情况下文件必须可读,使用MAP_SHARED则要有PROT_WRITE以及该文件要能写入。
EINVAL          参数start、length 或offset有一个不合法。
EAGAIN         文件被锁住,或是有太多内存被锁住。
ENOMEM      内存不足。

  • 3
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
基于arm开发板的2048游戏的实现:实现功能及其原理如下: 2048是平面二维游戏,在4*4图片方格内,通过对滑动方向(上、下、左、右)的判断实 现对各个图片的移动、合并(在沿滑动方向上,两相邻元素值相等或者两相等元素值之间 的元素内容为空(即为0),即要进行合并)等操作。 首先:需要实现的是在屏幕上显示出相应界面,这涉及到对lcd屏幕的操作,arm开发版运行 的是linux系统,通过对设备文件(路径为/dev/fb0 的文件)进行操作,实现现屏幕显示功能。 因为是系统内的文件,采用系统IO函数实现,主要是open、read、write、lseek函数。同时 为了提高显示效率,还采用了mmap映射函数。 其次:该游戏需要判断出滑动的方向,来实现对相应图片的移动、合并操作,所以还需要对 触摸屏设备文件(路径名为/dev/input/event0 的设备文件)进行操作。要判断出滑动类型, 获取点下屏幕时的坐标点x1、y1以及离开屏幕时的坐标点x2、y2。根据两值只差可判断出 滑动方向(差值绝对值大的,滑动方向就是哪边) 实现对图画的移动、合并操作,这是本游戏设计的一大难点,本项目 采用如下方法实现该功能: 该游戏本质上是对二维数组的操作,该项目,定义了如下量 //该节点用来保存4*4二维数组每一个元素的信息 struct position { int x; int y; int data; char *names; }; struct position * pos[4][4] = {0}; char *name[12]; //指向要显示图片的路径名 结构体用来保存二维数组每一个元素的信息,x、y保存的是显示图片的位置信息, data保存的是图片对应的值(根据此值可以显示出相应的图片,如果值为8,则显示值 为8的图片),names是一个字符型指针,指向的是要显示图片的路径名信息(该信息保 存在char *name[12]的指针数组,该数组指针保存了路径名信息)。 据此,便可以显示出相应的图片,接下来便是操作 pos[4][4]是一个二维数组,当朝着一个方向滑动时,便需要根据pos->data 值进行 相关操作 ,研滑动方向上,判断第一个元素值是否为0(空白图片表示值为0),如果为0 则继续找,直到找到下一个不为0的元素,然后将该值赋值给开头元素,该元素置0, 如果开头元素不为0,那么就往后面寻找,直到找到一个不为0的元素,如果该元素与开头元素 值相等,则合并(开头元素值乘以2,然后该元素置0)。以上便是一轮判断,然后开头元素再 往后挪一个,按照同样的方法判断,进行相关操作。 然后,还需要有产生随机数的功能, 定义了两个值XX ,YY,用rand函数产生小于4的两个数,然后对二维数组pos进行遍历, 如果pos[i][j]->data == pos[XX][YY]->data 那么就可以在改位置产生随机数,否则,就重新产 生一次随机数,直到产生为止,产生不了则游戏结构 最后, 为了实现计分功能,通过计算,在像素坐标点为(50,20)(75,20)(100,20)(125,20)的位置显示出0到9的数字, 通过计分,可以将所得分数在该四个点显示出
教程非常不错,价值280元,绝对是干货 Linux网络编程(总共41集) 讲解Linux网络编程知识,分以下四个篇章。 Linux网络编程之TCP/IP基础篇 Linux网络编程之socket编程篇 Linux网络编程之进程间通信篇 Linux网络编程之线程篇 Linux网络编程之TCP/IP基础篇 01TCPIP基础(一) ISO/OSI参考模型 TCP/IP四层模型 基本概念(对等通信、封装、分用、端口) 02TCPIP基础(二) 最大传输单元(MTU)/路径MTU 以太网帧格式 IC MP ARP RARP 03TCPIP基础(三) IP数据报格式 网际校验和 路由 04TCPIP基础(四) TCP特点 TCP报文格式 连接建立三次握手 连接终止四次握手 TCP如何保证可靠性 05TCPIP基础(五) 滑动窗口协议 UDP特点 UDP报文格式 Linux网络编程之socket编程篇 06socket编程(一) 什么是socket IPv4套接口地址结构 网络字节序 字节序转换函数 地址转换函数 套接字类型 07socket编程(二) TCP客户/服务器模型 回射客户/服务器 socket、bind、listen、accept、connect 08socket编程(三) SO_REUSEADDR 处理多客户连接(process-per-conection) 点对点聊天程序实现 09socket编程(四) 流协议与粘包 粘包产生的原因 粘包处理方案 readn writen 回射客户/服务器 10socket编程(五) read、write与recv、send readline实现 用readline实现回射客户/服务器 getsockname、getpeername gethostname、gethostbyname、gethostbyaddr 11socket编程(六) TCP回射客户/服务器 TCP是个流协议 僵进程与SIGCHLD信号 12socket编程(七) TCP 11种状态 连接建立三次握手、连接终止四次握手 TIME_WAIT与SO_REUSEADDR SIGPIPE 13socket编程(八) 五种I/O模型 select 用select改进回射客户端程序 14socket编程(九) select 读、写、异常事件发生条件 用select改进回射服务器程序。 15socket编程(十) 用select改进第八章点对点聊天程序 16socket编程(十一) 套接字I/O超时设置方法 用select实现超时 read_timeout函数封装 write_timeout函数封装 accept_timeout函数封装 connect_timeout函数封装 17socket编程(十二) select限制 poll 18socket编程(十三) epoll使用 epoll与select、poll区别 epoll LT/ET模式 19socket编程(十四) UDP特点 UDP客户/服务基本模型 UDP回射客户/服务器 UDP注意点 20socket编程(十五) udp聊天室实现 21socket编程(十六) UNIX域协议特点 UNIX域地址结构 UNIX域字节流回射客户/服务 UNIX域套接字编程注意点 22socket编程(十七) socketpair sendmsg/recvmsg UNIX域套接字传递描述符字 Linux网络编程之进程间通信篇 23进程间通信介绍(一) 进程同步与进程互斥 进程间通信目的 进程间通信发展 进程间通信分类 进程间共享信息的三种方式 IPC对象的持续性 24进程间通信介绍(二) 死锁 信号量 PV原语 用PV原语解决司机与售票员问题 用PV原语解决民航售票问题 用PV原语解决汽车租赁问题 25System V消息队列(一) 消息队列 IPC对象数据结构 消息队列结构 消息队列在内核的表示 消息队列函数 26System V消息队列(二) msgsnd函数 msgrcv函数 27System V消息队列(三) 消息队列实现回射客户/服务器 28共享内存介绍 共享内存 共享内存示意图 管道、消息队列与共享内存传递数据对比 mmap函数 munmap函数 msync函数 29System V共享内存 共享内存数据结构 共享内存函数 共享内存示例 30System V信号量(一) 信号量 信号量

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

为幸福写歌

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值