我是靠谱客的博主 无奈凉面,最近开发中收集的这篇文章主要介绍mmap系统调用使用-学习笔记1. mmap函数参数说明2. mmap父子进程通信3. 匿名映射4. mmap基本使用示例5. mmap使用常见问题6. 总结,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

文章目录

  • 1. mmap函数参数说明
  • 2. mmap父子进程通信
  • 3. 匿名映射
  • 4. mmap基本使用示例
  • 5. mmap使用常见问题
  • 6. 总结

1. mmap函数参数说明

头文件:#include <unistd.h> #include <sys/mman.h>

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

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

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

2. mmap父子进程通信

父子等有血缘关系的进程之间也可以通过mmap建立的映射区来完成数据通信。但相应的要在创建映射区的时候指定对应的标志位参数flags:
MAP_PRIVATE:(私有映射)父子进程各自独占映射区;
MAP SHARED:(共享映射)父子进程共享映射区.

问:父进程创建映射区,然后fok子进程,子进程修改映射区内容,而后,父进程读取映射区内容,查验是否共享。
答:父子进程共享:
1.打开的文件
2.mmap建立的映射区(但必须要使用MAP_SHARED)

3. 匿名映射

通过使用我们发现,使用映射区来完成文件读写操作十分方便,父子进程间通信也较容易。但缺陷是,每次创建映射区一定要依赖一个文件才能实现。通常为了建立映射区要open一个temp文件,创建好了再unlink、close掉,比较麻烦。可以直接使用匿名映射来代替。其实Linux系统给我们提供了创建匿名映射区的方法,无需依赖一个文件即可创建映射区。同样需要借助标志位参数flags来指定。
使用MAP_ANONYMOUS(或MAP_ANON),如:

int *p mmap(NULL,4,PROT_READ|PROT_WRITE,MAP_SHARED MAP_ANONYMOUS, -1, 0);

"4"随意举例,该位置表大小,可依实际需要填写。

需注意的是,MAP_ANONYMOUS和MAP_ANON这两个宏是Linux操作系统特有的宏。在类Unix系统中如无该宏定义,可使用如下两步来完成匿名映射区的建立。

fd = open("/dev/zero",O RDWR);
p = mmap(NULL,size,PROT_READ |PROT_WRITE,MMAP_SHARED,fd,0);

4. mmap基本使用示例

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
int test01() {
int len = 0;
int ret = 0;
int fd = open("mytest.txt", O_CREAT | O_RDWR, 0644);
if (fd < 0) {
printf("open failedn");
exit(1);
}
len = ftruncate(fd, 4);
if (len == -1) {
printf("ftruncate error!n");
exit(1);
}
p = mmap(NULL, 4, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (p == MAP_FAILED) {
printf("mmap error!n");
exit(1);
}
strcpy(p, "abc");
ret = munmap(p, 4);
if (ret == -1) {
printf("munmap failed!n");
exit(1);
}
close(fd);
return 0;
}

5. mmap使用常见问题

1. Q:可以open的时候O_CREAT一个新文件来创建映射区吗?
A:可以,但不能创建大小为0(mmap第二个参数)的映射区,使用ftruncate指定文件大小。

2. Q:如果p++,munmap可否成功?
A:失败,mmap和munmap的地址必须一致。

3. Q:如果open时O RDONLY,mmap时PROT参数指定PROT READ|PROT WRITE会怎样?
A:失败,permission denied。创建映射区的必须小于等于打开文件的权限;创建映射区隐藏的读文件操作。所以mmap参数必须要有读权限。

4. Q:如果文件偏移量为1000会怎样?
A:最后一个参数offset必须是0或者4K的整数倍 ,mmu创建的映射区,单位是4K。

6. Q:如果不检测mmap的返回值,会怎样?
A:各种失败。

7. Q:mmap什么情况下会调用失败?
A: mmap申请的空间不能大于文件大小。

8. Q:对mem越界操作会怎样?
A:同1

9. Q:文件描述符先关闭,对mmap映射有没有影响?
A:没有影响,mmap分配映射区后,通过地址来操作该空间,不使用fd操作。

6. 总结

使用mmap时务必注意以下事项:

 1. 创建映射区的过程中,隐含着一次对映射文件的读操作。
2. 当MAP_SHARED时,要求:映射区的权限应<=文件打开的权限(出于对映射区的保护)。而MAP_PRIVATE则无所谓,因为mmap中的权限是对内存的限制。
3. 映射区的释放与文件关闭无关。只要映射建立成功,文件可以立即关闭。
4. 特别注意,当映射文件大小为0时,不能创建映射区。所以:用于映射的文件必须要有实际大小!!mmap使用时常常会出现总线错误,通常是由于共享文件存储空间大小引起的。
5. munmap传入的地址一定是mmap的返回地址。坚决杜绝指针++操作。
6. 如果文件偏移量必须为4K的整数倍
7. mmap创建映射区出错概率非常高,一定要检查返回值,确保映射区建立成功再进行后续操作。

最后

以上就是无奈凉面为你收集整理的mmap系统调用使用-学习笔记1. mmap函数参数说明2. mmap父子进程通信3. 匿名映射4. mmap基本使用示例5. mmap使用常见问题6. 总结的全部内容,希望文章能够帮你解决mmap系统调用使用-学习笔记1. mmap函数参数说明2. mmap父子进程通信3. 匿名映射4. mmap基本使用示例5. mmap使用常见问题6. 总结所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(52)

评论列表共有 0 条评论

立即
投稿
返回
顶部