Linux系统调用--mmap/munmap函数详解【转】
功能描述:
mmap将一个文件或者其它对象映射进内存。文件被映射到多个页上,如果文件的大小不是所有页的大小之和,最后一个页不被使用的空间将会清零。munmap执行相反的操作,删除特定地址区域的对象映射。
基
于文件的映射,在mmap和munmap执行过程的任何时刻,被映射文件的st_atime可能被更新。如果st_atime字段在前述的情况下没有得到
更新,首次对映射区的第一个页索引时会更新该字段的值。用PROT_WRITE 和 MAP_SHARED标志建立起来的文件映射,其st_ctime
和 st_mtime
在对映射区写入之后,但在msync()通过MS_SYNC 和 MS_ASYNC两个标志调用之前会被更新。
用法:
#include
void *mmap(void *start, size_t length, int prot, int flags,
int fd, off_t offset);
int munmap(void *start, size_t length);
参数:
start:映射区的开始地址。
length:映射区的长度。
prot:期望的内存保护标志,不能与文件的打开模式冲突。是以下的某个值,可以通过or运算合理地组合在一起
PROT_EXEC //页内容可以被执行
PROT_READ //页内容可以被读取
PROT_WRITE //页可以被写入
PROT_NONE //页不可访问
flags:指定映射对象的类型,映射选项和映射页是否可以共享。它的值可以是一个或者多个以下位的组合体
MAP_FIXED //使用指定的映射起始地址,如果由start和len参数指定的内存区重叠于现存的映射空间,重叠部分将会被丢弃。如果指定的起始地址不可用,操作将会失败。并且起始地址必须落在页的边界上。
MAP_SHARED //与其它所有映射这个对象的进程共享映射空间。对共享区的写入,相当于输出到文件。直到msync()或者munmap()被调用,文件实际上不会被更新。
MAP_PRIVATE //建立一个写入时拷贝的私有映射。内存区域的写入不会影响到原文件。这个标志和以上标志是互斥的,只能使用其中一个。
MAP_DENYWRITE //这个标志被忽略。
MAP_EXECUTABLE //同上
MAP_NORESERVE //不要为这个映射保留交换空间。当交换空间被保留,对映射区修改的可能会得到保证。当交换空间不被保留,同时内存不足,对映射区的修改会引起段违例信号。
MAP_LOCKED //锁定映射区的页面,从而防止页面被交换出内存。
MAP_GROWSDOWN //用于堆栈,告诉内核VM系统,映射区可以向下扩展。
MAP_ANONYMOUS //匿名映射,映射区不与任何文件关联。
MAP_ANON //MAP_ANONYMOUS的别称,不再被使用。
MAP_FILE //兼容标志,被忽略。
MAP_32BIT //将映射区放在进程地址空间的低2GB,MAP_FIXED指定时会被忽略。当前这个标志只在x86-64平台上得到支持。
MAP_POPULATE //为文件映射通过预读的方式准备好页表。随后对映射区的访问不会被页违例阻塞。
MAP_NONBLOCK //仅和MAP_POPULATE一起使用时才有意义。不执行预读,只为已存在于内存中的页面建立页表入口。
fd:有效的文件描述词。如果MAP_ANONYMOUS被设定,为了兼容问题,其值应为-1。
offset:被映射对象内容的起点。
返回说明:
成功执行时,mmap()返回被映射区的指针,munmap()返回0。失败时,mmap()返回MAP_FAILED[其值为(void *)-1],munmap返回-1。errno被设为以下的某个值
EACCES:访问出错
EAGAIN:文件已被锁定,或者太多的内存已被锁定
EBADF:fd不是有效的文件描述词
EINVAL:一个或者多个参数无效
ENFILE:已达到系统对打开文件的限制
ENODEV:指定文件所在的文件系统不支持内存映射
ENOMEM:内存不足,或者进程已超出最大内存映射数量
EPERM:权能不足,操作不允许
ETXTBSY:已写的方式打开文件,同时指定MAP_DENYWRITE标志
SIGSEGV:试着向只读区写入
SIGBUS:试着访问不属于进程的内存区
原文地址:
http://club.cn.yahoo.com/bbs/threadview/1200062866_53__pn1.html
本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u2/74012/showart_1091637.html
------------------------------
linux/unix 下,或者说posix 的munmap,很简单,只有两个参数:
int munmap(void *start, size_t length);
其中 length 必须是 mmap 时的 length,如果小于当初 mmap 时的那个 length,并且正好少的部分跨越了一个page,那就麻烦了,我就犯了这个错误,非常严重的后果!内存泄漏,不是泄露了刚好少 unmap 的那个 page,而是整个 [start, length) 区域都不会成功被 unmap,也许内存中的更改已经写入文件,但是虚拟内存空间[start,length)未被释放!如此多次,会造成 ENOMEM!
感谢上帝,搞了半天,这个问题终于被发现了。
感觉吧,Windows 的很简单 UnmapViewOfFile 就一个参数,就是 MapViewOfFile 返回的那个地址,UnmapViewOfFile 时整个 map 区域都被释放,而 posix 的 munmap,从理论上讲,可以一次 mmap 一大块区域,然后多次 unmap 这个区域中的不同部分,这的确提高了一些灵活性,但是……。
Linux系统调用--mmap/munmap函数详解【转】的更多相关文章
- Linux C 中 fork() 函数详解
一.fork入门知识 一个进程,包括代码.数据和分配给进程的资源.fork() 函数通过系统调用创建一个与原来进程几乎完全相同的进程,也就是两个进程可以做完全相同的事,但如果初始参数或者传入的变量不同 ...
- (笔记)Linux下的ioctl()函数详解
我这里说的ioctl函数是指驱动程序里的,因为我不知道还有没有别的场合用到了它,所以就规定了我们讨论的范围.写这篇文章是因为我前一阵子被ioctl给搞混了,这几天才弄明白它,于是在这里清理一下头脑. ...
- [fork]Linux中的fork函数详解
---------------------------------------------------------------------------------------------------- ...
- Linux内核中kzalloc函数详解
**************************************************************************************************** ...
- Linux下的ioctl()函数详解
我这里说的ioctl函数是指驱动程序里的,因为我不知道还有没有别的场合用到了它,所以就规定了我们讨论的范围.写这篇文章是因为我前一阵子被ioctl给搞混了,这几天才弄明白它,于是在这里清理一下头脑. ...
- Linux操作系统shell与函数详解
shell和函数的定义 1. linux shell 函数 将一组命令集或语句形成一个可用的块, 这些语句块称为函数. 2. shell 函数的组成 函数名:函数名字,注意一个脚本中函数名要唯一, ...
- 【Linux 进程】fork函数详解
一.fork入门知识 一个进程,包括代码.数据和分配给进程的资源.fork()函数通过系统调用创建一个与原来进程几乎完全相同的进程,也就是两个进程可以做完全相同的事,但如果初始参数或者传入的变量不同, ...
- Linux 系统 文件锁 fcntl函数详解
#include <unistd.h> #include <fcntl.h> int fcntl(int fd, int cmd); int fcntl(int fd, int ...
- Linux内核中container_of函数详解
http://www.linuxidc.com/Linux/2016-08/134481.htm
随机推荐
- docker:从 tomcat 容器连接到 mysql 容器
docker 中的容器互联是一个较为复杂的话题,详细内容将在后续章节中介绍. 续前 2 个章节的内容,我们创建了一个 mysql 容器和一个 tomcat 容器,可以使用 「docker ps」来查看 ...
- lodash的运用
Object 对象 1._.merge(object, [sources]) 此方法类似于_.assign,除了它递归地将源对象的自有和继承的可枚举字符串键控属性合并到目标对象中. 如果存在目标值,将 ...
- 用java给php写个万能接口
package helloworld; import java.io.IOException; import javax.servlet.ServletException; import javax. ...
- Power-BI免费版常用功能之同比、环比
Power-BI免费版也可以实现同比.环比的功能.要实现同比.环比的功能,要在筛选行添加年份.月的筛选,并且指定某年份.月份.场景:如图想要在简表中显示上年收入.收入同比.收入同比差值.上月收入.收入 ...
- C# 读取app.config配置文件节点键值,提示"配置系统未能初始化" 错误的解决方案
MSDN里写到, 如果配置文件中包含 configSections 元素,则 configSections 元素必须是 configuration 元素的第一个子元素. 将自己添加的appSettin ...
- Spring Boot 1 创建Demo
Spring Boot的主要优点: 为所有Spring开发者更快的入门 开箱即用,提供各种默认配置来简化项目配置 内嵌式容器简化Web项目 没有冗余代码生成和XML配置的要求 入门操作: 1.打开ht ...
- play项目部署
首先对于现场的数据库,一定要谨慎谨慎再谨慎,特别是保存有重要数据的. 使用expdp命令导入数据库: 事前准备: 1.确保linux服务器上已经正确安装oracle (10g以上版本) 2.有Xshe ...
- 一次数据库hang住的分析过程
现象: 普通用户和sysdba都无法登陆,业务中断 分析过程: 1.先做hanganalyze和systemstate dump $sqlplus -prelim "/as sysdba&q ...
- Simple GDB case
to be added... gdb a.out [Inferior 1 (process 9718) exited with code 05] (gdb) list Line number ...
- Swift游戏实战-跑酷熊猫 04 熊猫的跳和滚的动作
这节内容,我们利用上一节学过的内容,给熊猫添加跳和滚动的动作.同时通过重载touchBegan方法来响应动作.切换跑,跳,滚. 要点: 通过序列帧纹理产生动画: SKAction.animatWith ...