1.mmap-创建内存映射

作用:将磁盘文件的数据映射到内存,用户通过内存就能修改磁盘文件

函数原型:

  1. void *mmap{

  2. void *addr; //映射区首地址,传NULL

  3. size_t length; //映射区的大小

  4. //会自动调为4k的整数倍

  5. //不能为0

  6. //一般文件多大,length就指定多大

  7. int prot; //映射区权限

  8. //PROT_READ 映射区比必须要有读权限

  9. //PROT_WRITE

  10. //PROT_READ | PROT_WRITE

  11. int flags; //标志位参数

  12. //MAP_SHARED 修改了内存数据会同步到磁盘

  13. //MAP_PRIVATE 修改了内存数据不会同步到磁盘

  14. int fd; //要映射的文件对应的fd

  15. off_t offset; //映射文件的偏移量,从文件的哪里开始操作

  16. //映射的时候文件指针的偏移量

  17. //必须是4k的整数倍

  18. //一般设置为0

  19. }

返回值:

映射区的首地址-调用成功

调用失败:MAP_FALED

2.munmap-释放内存映射区

函数原型:int munmap(void *addr,size_t length);

addr-mmap的返回值

length-mmap的第二个参数

3.注意事项

问:如果对mmap的返回值(ptr)做++操作(ptr++), munmap是否能够成功?
答:不能
问:如果open时O_RDONLY, mmap时prot参数指定PROT_READ | PROT_WRITE会怎样?
答mmap调用失败
open文件指定权限应该大于等于mmap第三个参数prot指定的权限
问:如果文件偏移量为1000会怎样?
答:必须是4096的整数倍
问:mmap什么情况下会调用失败?
第二个参数length = 0
第三个参数必须指定PROT_READ
fd对应的打开权限必须大于等于port权限
偏移量:必须是4096的整数倍
问:可以open的时候O_CREAT一个新文件来创建映射区吗?
答:可以,需要做文件拓展
lseek
truncate(path,length)
问:mmap后关闭文件描述符,对mmap映射有没有影响?
答:没有
问:对ptr越界操作会怎样?
答:段错误

4.mmap使用

(1)基本代码

  1. #include <stdio.h>

  2. #include <unistd.h>

  3. #include <stdlib.h>

  4. #include <sys/types.h>

  5. #include <sys/stat.h>

  6. #include <string.h>

  7. #include <sys/mman.h>

  8. #include <fcntl.h>

  9. int main(int argc, const char* argv[])

  10. {

  11. //打开一个文件

  12. int fd=open("english.txt",O_RDWR);

  13. int len=lseek(fd,0,SEEK_END);

  14. //创建内存映射区

  15. void *ptr=mmap(NULL,len,PROT_READ | PROT_WRITE,MAP_SHARED,fd,0);

  16. if(ptr==MAP_FAILED)

  17. {

  18. perror("mmap error");

  19. exit(1);

  20. }

  21. printf("%s",(char*)ptr);

  22. //释放内存映射区

  23. munmap(ptr,len);

  24. close(fd);

  25. return 0;

  26. }

运行结果:

  1. wangkai@wangkai-HP-242-G1-Notebook-PC:~/0110/6Day$ ./mmap

  2. sadaskdkasj

  3. sdasdasd

  4. asdasdsadasds

  5. dasdas

(2)使用mmap进行有血缘关系的进程间通信

  1. #include <stdio.h>

  2. #include <unistd.h>

  3. #include <stdlib.h>

  4. #include <sys/types.h>

  5. #include <sys/stat.h>

  6. #include <string.h>

  7. #include <sys/mman.h>

  8. #include <sys/wait.h>

  9. #include <fcntl.h>

  10. /*

  11. 利用mmap进行父子间通信,效率比文件I/O高,

  12. 数据不是从磁盘上读,而是从内存上读写

  13. 不阻塞,所以读之前一定要写好

  14. */

  15. int main(int argc, const char* argv[])

  16. {

  17. //打开一个文件

  18. int fd=open("english.txt",O_RDWR);

  19. int len=lseek(fd,0,SEEK_END);

  20. //创建内存映射区

  21. void *ptr=mmap(NULL,len,PROT_READ | PROT_WRITE,MAP_SHARED,fd,0);

  22. if(ptr==MAP_FAILED)

  23. {

  24. perror("mmap error");

  25. exit(1);

  26. }

  27. close(fd);

  28. //创建子进程

  29. pid_t pid=fork();

  30. if(pid==-1)

  31. {

  32. perror("fork error");

  33. exit(1);

  34. }

  35. if(pid>0)

  36. {

  37. //写数据

  38. strcpy((char*)ptr,"我是你爸爸");

  39. //回收子进程

  40. wait(NULL);

  41. }

  42. else if(pid==0)

  43. {

  44. //读数据

  45. printf("%s\n",(char*)ptr);

  46. }

  47. printf("%s",(char*)ptr);

  48. //释放内存映射区

  49. munmap(ptr,len);

  50. return 0;

  51. }

(3)创建匿名映射区

  1. int len=4096;

  2. //创建匿名内存映射区,不指定文件

  3. void *ptr=mmap(NULL,len,PROT_READ | PROT_WRITE,MAP_SHARED | MAP_ANON,-1,0);

效果和(2)一样。

(4)没有血缘关系的进程间通信

写代码

  1. //mmap_w_ipc.c

  2. #include <stdio.h>

  3. #include <stdlib.h>

  4. #include <string.h>

  5. #include <unistd.h>

  6. #include <sys/types.h>

  7. #include <sys/mman.h>

  8. #include <fcntl.h>

  9. int main(int argc, char *argv[])

  10. {

  11. int fd = open("temp", O_RDWR | O_CREAT, 0664);

  12. void* ptr = mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);

  13. if(ptr == MAP_FAILED)

  14. {

  15. perror("mmap");

  16. exit(1);

  17. }

  18. while(1)

  19. {

  20. char*p = (char*)ptr;

  21. p += 1024;

  22. strcpy(p, "hello parent, i am your 朋友!!!\n");

  23. sleep(2);

  24. }

  25. // 释放

  26. int ret = munmap(ptr, 8192);

  27. if(ret == -1)

  28. {

  29. perror("munmap");

  30. exit(1);

  31. }

  32. return 0;

  33. }

读代码

  1. //mmap_r_ipc.c

  2. #include <stdio.h>

  3. #include <stdlib.h>

  4. #include <string.h>

  5. #include <unistd.h>

  6. #include <sys/types.h>

  7. #include <sys/mman.h>

  8. #include <fcntl.h>

  9. int main(int argc, char *argv[])

  10. {

  11. int fd = open("temp", O_RDWR | O_CREAT, 0664);

  12. ftruncate(fd, 4096);

  13. int len = lseek(fd, 0, SEEK_END);

  14. void* ptr = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);

  15. if(ptr == MAP_FAILED)

  16. {

  17. perror("mmap");

  18. exit(1);

  19. }

  20. while(1)

  21. {

  22. sleep(1);

  23. printf("%s\n", (char*)ptr+1024);

  24. }

  25. // 释放

  26. int ret = munmap(ptr, len);

  27. if(ret == -1)

  28. {

  29. perror("munmap");

  30. exit(1);

  31. }

  32. return 0;

  33. }

小结

1. 进程间通信

a. 有血缘关系的
父子进程共享内存映射区
    b. 没有血缘关系的进程间通信
i. 如何通信?
不能使用匿名映射的方式
只能借助磁盘文件创建映射区 - hello
不阻塞
ii. a(a.c)  b(b.c)
a.c
int fd = open("hello");
void* ptr = mmap(,,,,,fd, 0);
对映射区进行读写操作

b.c
int fd1 = open("hello");
void* ptr1 = mmap(,,,,fd1, 0);

对映射区做读写操作

2. mmap 实现内存映射

a. 必须有一个文件
b. 文件数据什么时候有用:
i. 单纯文件映射
ii. 进程间通信:
1) 文件数据是没有用的

3. 如果创建匿名映射区

mmap的时候:
    第二个参数:指定映射区大小
    第四个参数:需要添加MAP_ANON宏
    第五个参数:-1

4. 父子进程永远共享的东西?

文件描述符
内存映射区

mmap函数参数讲解相关推荐

  1. mmap()函数参数详解

    author : wfs time : 2019.4.17 功能描述 mmap将一个文件或者其它对象映射进内存.文件被映射到多个页上,如果文件的大小不是所有页的大小之和,最后一个页不被使用的空间将会清 ...

  2. 【Android 逆向】Android 进程注入工具开发 ( 注入代码分析 | 远程调用 目标进程中 libc.so 动态库中的 mmap 函数 二 | 准备参数 | 远程调用 mmap 函数 )

    文章目录 一.准备 mmap 函数的参数 二.mmap 函数远程调用 一.准备 mmap 函数的参数 上一篇博客 [Android 逆向]Android 进程注入工具开发 ( 注入代码分析 | 远程调 ...

  3. python batchnorm2d_BatchNorm2d原理、作用及其pytorch中BatchNorm2d函数的参数讲解

    BN原理.作用: 函数参数讲解: BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True) 1. ...

  4. 【Android 逆向】Android 进程注入工具开发 ( 注入代码分析 | 远程调用 目标进程中 libc.so 动态库中的 mmap 函数 一 | mmap 函数简介 )

    文章目录 一.mmap 简介 二.mmap 函数作用 一.mmap 简介 mmap 函数的作用是 将 文件 映射到 内存中 , 映射的单位必须是 PAGE_SIZE ; mmap 函数引入头文件 : ...

  5. C语言函数输入/输出【IN/OUT】参数讲解

    数据结构是编程的核心,还是算法是编程的核心,这一直是一个争论的话题.正因为如此,说明了数据结构与算法在编程领域的核心地位.------程序员 苏格拉没有底与糕点 苏格拉没有底是一个伟大的哲学家,他很喜 ...

  6. C/C++中二维数组作为函数参数------方法及要点讲解

    ** 1,形参给出第二维的长度. ** C/C++中二维数组作为函数参数 的时候,可以不写行号,但是一定要写明列号(一定注意,一定注意,一定注意!). int array[3][3]; 函数声明:vo ...

  7. php中年月日用什么参数,PHP中date()日期函数参数整理

    PHP中date()日期函数参数整理 发布于 2014-11-19 13:34:06 | 105 次阅读 | 评论: 0 | 来源: 网友投递 PHP开源脚本语言PHP(外文名: Hypertext ...

  8. php脚本函数,PHP执行系统命令函数实例讲解

    命令注入 命令注入(Command Injection),对一些函数的参数没有做过滤或过滤不严导致的,可以执行系统或者应用指令(CMD命令或者 bash 命令)的一种注入攻击手段. 常见的执行系统命令 ...

  9. 共享内存简介和mmap 函数

    一.共享内存简介 共享内存区是最快的IPC形式,这些进程间数据传递不再涉及到内核,换句话说是进程不再通过执行进入内核的系统调用来传递彼此的数据. 即每个进程地址空间都有一个共享存储器的映射区,当这块区 ...

最新文章

  1. 获取 一个文件 在沙盒Library/Caches/ 目录下的路径
  2. java旅游网站毕业论文,基于JAVA技术的旅游网站的开发.doc
  3. 十年之后,CV经典教材《计算机视觉:算法与应用》迎来第二版,初稿开放下载...
  4. 我们究竟还要学习哪些Android知识?专题解析
  5. Condition_number
  6. Android调用WebService
  7. STM32学了很久,我还是不会做项目。
  8. Java中反射机制(Reflection)学习
  9. 使用 python 开发 Web Service
  10. Hibernate 延迟加载(一)
  11. 微软鲍尔默:IE9浏览器将会在3月发布
  12. Spring 注解教程
  13. mfc在调整界面时左边的控件会丢失_Qt项目中如何完成一个漂亮的界面
  14. 判断参数并赋予默认值
  15. P3195 [HNOI2008]玩具装箱TOY DP+优化
  16. c语言ll 1 语法分析器,LL(1)语法分析器的设计与实现
  17. 纪念我那悲苦的黑色草莓米糕
  18. IT产业第一定律:摩尔定理
  19. java.sql.SQLException: The server time zone value‘xxxxxxxx‘ is unrecognized
  20. 【嵌入式软件开发岗位 ---- 面试总结01】

热门文章

  1. c语言入门自学宝典,c语言学习编程宝典下载-c语言学习编程宝典appv1.2 - 起点软件园...
  2. n1 openwrt 挂载u盘_[Openwrt 扩展上篇]USB挂载U盘启动Samba共享
  3. oracle 051考试,OCP/OCA认证考试指南全册Oracle Database 11g(1Z0-051,1Z0-052,1Z0-053)练习与知识点...
  4. [转]【Unity3D入门教程】Unity3D简介、安装和程序发布
  5. 第四章:宽带滤光片中颜色的作用
  6. 怎么用wps抽签_怎么用WPS做活动抽签用的PPT?有模板可以给我更好!
  7. JAVA实现PDF和EXCEL生成和数据动态插入以及导出
  8. 【图像去噪】基于边缘增强扩散 (cEED) 和 Coherence Enhancing Diffusion (cCED) 滤波器实现图像去噪附matlab代码
  9. H5页面实现摇一摇(微信+APP内嵌入使用)
  10. 十分钟带你了解计算思维