保护权限
mmap函数的prot参数可指定内存映射区的保护权限,例如指定PROT_READ和PROT_EXEC,在调用open打开文件就应该指定O_RDONLY或者O_RDWR。如果指定了PROT_WRITE,打开的文件应该使用O_WRONLY或者O_RDWR。
由于一些硬件架构对于内存的保护粒度有所不同,情况会变的有些复杂:
1. 一般打开文件指定O_RDWR标记就已经满足基本的使用了。
2. 如果prot参数只指定了PROT_WRITE,且open以O_WRONLY标记打开文件,内存映射的保护权限和打开文件的权限理论上是兼容的,但是调用mmap却会失败,设置errno为EACCES错误。因为一些硬件架构上PROT_WRITE隐含了PROT_READ,这意味着系统分页可写也可读,但这与O_WRONLY标记实际上是不兼容的(这与硬件架构有关系)。
3. 以O_RDONLY标记打开一个文件,mmap调用指定了MAP_PRIVATE创建私有内存映射,因为MAP_PRIVATE映射上的修改操作不会反映到打开的文件中,所以prot参数可以指定任意的组合权限。
对于一个MAP_SHARED映射来说,在MAP_SHARED映射上的修改操作会反映到打开的文件中,唯一与O_RDONLY标记兼容的内存保护权限就是PROT_READ | PROT_EXEC。
2. 映射区域同步——msync
通常为确保映射区的数据写入物理磁盘上的文件中,在调用munmap解除映射前需要调用msync函数。前面我们没有调用msync函数依然能在文件中看到写入的数据,这是因为内核会自动将MAP_SHARED映射区的内容同步到打开的文件中,但内核并不保证何时同步数据。
通过调用msync函数可以让应用程序显式的控制文件与内存映射中的数据同步。
返回值:成功返回0,失败返回-1并设置errno
addr:需要同步的内存映射区起始地址
length:需要同步的数据大小
flags
内存映射主要分两种:文件映射和匿名映射。文件映射已经讲了,在映射过程中需要依赖一个文件,而匿名映射顾名思义就是创建匿名的映射区,不需要依赖文件。
可通过mmap函数的参数flags来指定MAP_ANONYMOUS (或MAP_ANON)创建一个匿名映射,由于不需要依赖文件,参数fd设置为-1,例如:
char *addr = mmap(NULL, 4, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0);
一般在linux上当指定了MAP_ANONYMOUS之后,会自动忽略参数fd的值,但是在类unix上可能必须指定MAP_ANONYMOUS并设置fd为-1,因此为了确保程序的可移植性,推荐这样做。
:设置同步数据的方式(MS_SYNC,MS_ASYNC,MS_INVALIDATE)