当前位置: 首页 > news >正文

linux 中mmap的用法

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

参数start(dst):指向欲映射的内存起始地址,通常设为 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)。

(src)

参数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 内存不足。

系统调用mmap()用于共享内存的两种方式:

(1)使用普通文件提供的内存映射:

适用于任何进程之间。此时,需要打开或创建一个文件,然后再调用mmap()

典型调用代码如下:

fd=open(name, flag, mode); if(fd<0) ...

ptr=mmap(NULL, len , PROT_READ|PROT_WRITE, MAP_SHARED , fd , 0); 

通过mmap()实现共享内存的通信方式有许多特点和要注意的地方,可以参看UNIX网络编程第二卷。

(2)使用特殊文件提供匿名内存映射:

适用于具有亲缘关系的进程之间。由于父子进程特殊的亲缘关系,在父进程中先调用mmap(),然后调用 fork()。那么在调用fork()之后,子进程继承父进程匿名映射后的地址空间,同样也继承mmap()返回的地址,这样,父子进程就可以通过映射区 域进行通信了。注意,这里不是一般的继承关系。一般来说,子进程单独维护从父进程继承下来的一些变量。而mmap()返回的地址,却由父子进程共同维护。 对于具有亲缘关系的进程实现共享内存最好的方式应该是采用匿名内存映射的方式。此时,不必指定具体的文件,只要设置相应的标志即可。 

  下面写一个demo:

   

[html]  view plain  copy
 
  1. #include <sys/mman.h>  
  2. #include <unistd.h>  
  3. #include <stdio.h>  
  4. #include <fcntl.h>  
  5. //#include "csapp.h"  
  6. #include <sys/stat.h>  
  7. #include <stdlib.h>  
  8. #include <string.h>  
  9. #include <errno.h>  
  10.   
  11. void mmapcopy(int fd, int size)  
  12. {  
  13.     char *bufp;  
  14.     //void * start_addr = 0;  
  15.     //start_addr = (void *)0x80000;  
  16.     bufp = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);  
  17.     if (bufp == (void *)-1)  
  18.     fprintf(stderr, "mmap: %s\n", strerror(errno));  
  19.       
  20.     memcpy(bufp, "Linuxdd", 7);  
  21.       
  22.     write(1, bufp, size);  
  23.     munmap(bufp, size);  
  24.     return;  
  25. }  
  26. int main(int argc, char **argv)  
  27. {  
  28.     struct stat stat;  
  29.     if (argc != 2)  
  30.         {  
  31.             printf("error.\n");  
  32.             exit(0);  
  33.         }  
  34.         //int fd = atoi(*argv[1]);  
  35.     //mmap()  
  36.     int fd = open(argv[1], O_RDWR, 0);  // O_RDWR 才能被读写。  
  37.     if (fd 0)  
  38.     fprintf(stderr, "open: %s\n", strerror(errno));  // 使用异常检查是个好习惯, 他可以帮助程序员迅速定位出错的地方!  
  39.     fstat(fd, &stat);  
  40.     mmapcopy(fd, stat.st_size);  
  41.     //while(1);  
  42.     close(fd);  
  43.     exit(0);  
  44. }  
 

 

转载于:https://www.cnblogs.com/Ph-one/p/6862041.html

相关文章:

  • platform_set_drvdata 和 platform_get_drvdata
  • 内核Alsa之pcm
  • MT6737 Android N 平台 Audio系统学习----录音到播放录音流程分析
  • 双链表的初始化,建立,插入,查找,删除。
  • 顺序栈的初始化,建立,插入,查找,删除。
  • 顺序队列的初始化,建立,插入,查找,删除。
  • 链队列的初始化,建立,插入,查找,删除。
  • 链栈的初始化,建立,插入,查找,删除。
  • 顺序串的初始化,建立,插入,查找,删除。
  • quick check
  • http://blog.csdn.net/renfufei/article/details/37725057/
  • github 博客模板
  • 好用的Markdown编辑器一览
  • 复旦大学考研科目
  • 51单片机GPIO口模拟串口通信
  • [ 一起学React系列 -- 8 ] React中的文件上传
  • 《深入 React 技术栈》
  • download使用浅析
  • es的写入过程
  • Facebook AccountKit 接入的坑点
  • JavaScript设计模式之工厂模式
  • Mysql5.6主从复制
  • Python_网络编程
  • 买一台 iPhone X,还是创建一家未来的独角兽?
  • 前端设计模式
  • 跳前端坑前,先看看这个!!
  • 学习使用ExpressJS 4.0中的新Router
  • 译自由幺半群
  • ​云纳万物 · 数皆有言|2021 七牛云战略发布会启幕,邀您赴约
  • $.type 怎么精确判断对象类型的 --(源码学习2)
  • (02)Cartographer源码无死角解析-(03) 新数据运行与地图保存、加载地图启动仅定位模式
  • (04)Hive的相关概念——order by 、sort by、distribute by 、cluster by
  • (14)学习笔记:动手深度学习(Pytorch神经网络基础)
  • (2)STM32单片机上位机
  • (C语言)深入理解指针2之野指针与传值与传址与assert断言
  • (附源码)springboot社区居家养老互助服务管理平台 毕业设计 062027
  • (提供数据集下载)基于大语言模型LangChain与ChatGLM3-6B本地知识库调优:数据集优化、参数调整、Prompt提示词优化实战
  • *1 计算机基础和操作系统基础及几大协议
  • .NET MVC之AOP
  • .NET版Word处理控件Aspose.words功能演示:在ASP.NET MVC中创建MS Word编辑器
  • .Net语言中的StringBuilder:入门到精通
  • ::
  • [ C++ ] STL---stack与queue
  • [].shift.call( arguments ) 和 [].slice.call( arguments )
  • [C#7] 1.Tuples(元组)
  • [CentOs7]图形界面
  • [CISCN2019 华北赛区 Day1 Web2]ikun
  • [docker] Docker容器服务更新与发现之consul
  • [Dxperience.8.*]报表预览控件PrintControl设置
  • [HeadFrist-HTMLCSS学习笔记][第一章Web语言:开始了解HTML]
  • [IDF]聪明的小羊
  • [LeetBook]【学习日记】获取子字符串 + 颠倒子字符串顺序
  • [leetcode] 四数之和 M
  • [MQ]常用的mq产品图形管理web界面或客户端
  • [MTK]安卓8 ADB执行ota升级