011mmap进程通信

article/2025/10/23 10:26:28

LINUX学习笔记

  • mmap 进程通信
    • 1. mmap 函数声明及头文件包含
      • 1.1 参数说明
      • 1.2 mmap 通信demo
    • 2. mmap 注意事项:
      • 2.1 mmap 函数的保险使用方法:
    • 3. demo 父子进程间mmap通信
    • 4. demo 非血缘关系进程间mmap通信
    • 5. mmap通信与fifo和文件通信的差异
    • 6. 匿名映射(只能用于血缘关系进程间通信)

mmap 进程通信

1. mmap 函数声明及头文件包含

man 2 mmap#include<sys/mman.h>
/* 创建映射区 */
void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);		
/* 释放映射区 */
int munmap(void *addr, size_t length);

1.1 参数说明

参数:

  • addr:指定映射区的首地址。通常传NULL,表示让系统自动分配
  • length:共享映射区的大小(<= 文件实际大小)
  • prot:共享内存区的读写属性
         PROT_READ
         PROT_WRITE
         PROT_READ | PROT_WRITE
  • flag:标注共享内存的共享属性
         MAP_SHARED(对内存的修改会反映到磁盘上)
         MAP_PRIVATE(对内存的修改不会反映到磁盘上)
  • fd:用于创建共享内存映射区的那个文件的 文件描述符
  • offset:从文件偏移位置开始建立映射区 (必须是4k的整数倍4096)默认0,表示映射文件全部

mmap返回值:

  • 成功—映射区的首地址
  • 失败—MAP_FAILED( 实质(void*)-1 ),设置errno
    !!!!!mmap 极易容易出错,切记一定要检查mmap的返回值!!!!!!

munmap返回值:

  • 成功— 0
  • 失败— -1,设置errno

1.2 mmap 通信demo

  1. open 创建一个文件,并用 lseek 或者 ftruncate 拓展文件大小
  2. mmap创建映射区
  3. 往映射区写
  4. 读映射区
  5. 释放映射区
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<errno.h>
#include<pthread.h>
#include<sys/mman.h>
#include<fcntl.h>void sys_error(const char * str)
{perror(str);exit(1);
}int main(int argc, char * argv [])
{int fd, ret;char* p = NULL;fd = open("testmap", O_RDWR | O_CREAT | O_TRUNC, 0644);if (fd < 0){sys_error("open error\n");}/*lseek(fd, 10 , SEEK_END);	// 与 ftruncate 等效write(fd, "\0", 1);*/ftruncate(fd, 10);			// 需要写权限才能拓展文件大小int len = lseek(fd, 0, SEEK_END);p = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);if (p == MAP_FAILED)   // 返回值一定要检查{sys_error("mmap error\n");}strcpy(p, "hello mmap");printf("------%s\n, p");ret = munmap(p, len);if (ret == -1)sys_error("munmap error\n");close(fd);return 0;}

有一个创建的 testmap 文件!并实现内存映射

2. mmap 注意事项:

  1. 用于创建映射区的文件大小为0,实际指定非0大小创建映射区,出“总线错误”
  2. 用于创建映射区的文件大小为0,实际制定0大小创建映射区,出“无效参数”
  3. 用于创建映射区的文件读写属性为 只读。映射区属性为 读|写, 出“无效参数”
  4. 创建映射区,需要read权限。(创建映射区的过程中,隐含着一次对映射文件的读操作)当访问权限指定为 MAP_SHARED 时mmap的读写权限,应该 <= 文件open权限。 只写不行
  5. 文件描述符fd,在mmap创建映射区完成即可关闭。后续访问文件,用 地址 访问
  6. offset必须是4096的整数倍。(MMU 映射的最小单位是 4k)
  7. 对申请的映射区内存,不能越界访问
  8. munmap 用于释放的地址,必须是mmap申请返回的地址,对申请的映射区地址做操作赋值之前应该备份一份地址用作munmap
  9. 映射区访问权限为“私有”MAP_PRIVATE,对内存所做的所有修改,只在内存有效,不会反映到物理磁盘上。
  10. 映射区访问权限为“私有”MAP_PRIVATE,只需要open文件有读权限,就可用于创建映射区。因为私有不反应到物理磁盘上面,没有写的过程

2.1 mmap 函数的保险使用方法:

1. fd = open("文件名", O_RDWR)
2. p = mmap(NULL,有效文件大小, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0)
3. close(fd)
4. munmap(p, length)

3. demo 父子进程间mmap通信

父子等有血缘关系的进程之间也可以通过 mmap 建立的映射区来完成数据通信。但相应的要在创建映射区的时候指定对应的标志位参数 flags:

  • MAP_SHARED(共享映射): 父子进程共享映射区
  • MAP_PRIVATE(私有映射):父子进程各自独占映射区(各自读各自的)
  1. open创建文件,ftruncate 拓展文件大小
  2. mmap 建立映射区
  3. close 关闭文件
  4. fork 创建子进程
  5. 对映射区进程写读操作(写读操作有先后顺序 靠sleep实现)
  6. 回收映射区
/* mmap_fork.c */
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<fcntl.h>
#include<sys/mman.h>
#include<sys/wait.h>int var = 100;int main(void)
{int *p;int fd;pid_t pid;fd = open("temp", O_RDWR | O_CREAT | O_TRUNC, 0644);if (fd < 0){perror("open error\n");exit(1);}ftruncate(fd, 4);p = (int*)mmap(NULL, 4, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);if (p == MAP_FAILED){perror("mmap error\n");exit(1);}close(fd);pid = fork();if (pid == 0){*p = 7000;   // 对映射区空间进行写操作var = 1000;printf("child, *p = %d, var = %d\n", *p, var);}else if(pid >0){sleep(1);printf("parent, *p = %d, var = %d\n", *p, var);wait(NULL);int ret = munmap(p,4);if (ret == -1){perror("munmap error\n");exit(1);}}return 0;
}

4. demo 非血缘关系进程间mmap通信

memcpy 函数:

memcpy --copy memory area------------
#include<string.h>void* memcpy(void* dest, void* src, size_t n);
---------------

写进程

  1. open创建文件,ftruncate 拓展文件大小
  2. mmap 创建映射区
  3. close关闭文件
  4. 往映射区内进行写操作
  5. 回收映射区
/* mmap_w.c */
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<errno.h>
#include<fcntl.h>
#include<sys/mman.h>void sys_error(const char * str)
{perror(str);exit(1);
}struct student{int id;char name[256];int age;
};int main(int argc, char * argv [ ])
{struct student stu = {0, "xiaoming", 18};struct student* p;int fd;fd = open("mmap_test", O_RDWR | O_CREAT |O_TRUNC, 0664);if (fd == -1)sys_error("open error\n");ftruncate(fd, sizeof(stu));p = (struct student*)mmap(NULL, sizeof(stu), PROT_READ |PROT_WRITE, MAP_SHARED, fd, 0);if (p == MAP_FAILED)sys_error("mmap error\n");close(fd);while(1){memcpy(p, &stu, sizeof(stu));stu.id++;sleep(1);}int ret = munmap(p, sizeof(stu));if (ret == -1){sys_error("munmap error\n");}return 0;}

读进程

  1. open打开写进程创建的文件
  2. mmap 建立映射区
  3. close关文件
  4. 读映射区内容
  5. 回收映射区
/* mmap_r.c */
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<errno.h>
#include<fcntl.h>
#include<sys/mman.h>void sys_error(const char * str)
{perror(str);exit(1);
}struct student{int id;char name[256];int age;
};int main(int argc, char * argv [])
{struct student stu;struct student* p;int fd;fd = open("mmap_test", O_RDONLY);if (fd == -1)sys_error("open error\n");p = (struct student*)mmap(NULL, sizeof(stu), PROT_READ , MAP_SHARED, fd, 0);if (p == MAP_FAILED)sys_error("mmap error\n");close(fd);while(1){printf("id = %d, name = %s, age = %d\n",p->id,p->name, p->age);sleep(1);}int ret = munmap(p, sizeof(stu));if (ret == -1){sys_error("munmap error\n");}}

编译、运行:

5. mmap通信与fifo和文件通信的差异

mmap 同 fifo 区别:

  • mmap:数据可以反复读取
  • fifo:数据只能一次读取

mmap 同 文件 区别:

  • mmap:映射到内存上,可以直接对内容进行指针操作
  • 文件:open、close 打开关闭文件,read、write 来实现文件通信

6. 匿名映射(只能用于血缘关系进程间通信)

通常为了创建映射区要 open 一个 temp 文件,创建好了在 close 掉,比较麻烦。在父子进程通信中,可以直接使用匿名映射来代替。Linux 借助 flags 位 MAP_ANONYMOUS 来实现。

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

PS:因为没有指定文件名,所以只限于有血缘关系进程间通讯

类似方法还有 /dev/zero

int fd = open("/dev/zero", O_RDWR);

http://chatgpt.dhexx.cn/article/HdqpCLRd.shtml

相关文章

Linux mmap内存映射

一、什么是mmap mmap是一种内存映射文件的方法&#xff0c;即将一个文件或者其它对象映射到进程的地址空间&#xff0c;实现文件磁盘地址和进程虚拟地址空间中一段虚拟地址的一一对映关系&#xff0c;函数原型如下 void *mmap(void *addr, size_t length, int prot, int flags,…

Linux下mmap

目录 一.mmap简介 二.为什么需要使用mmap 三.mmap的使用 四.mmap原理 一.mmap简介 什么是mmap了&#xff1f;从名字上来看是memory map也就是地址映射&#xff0c;是一种内存映射文件的方法。mmap是一个可以将一个文件或者其它对象映射到进程的地址空间实现磁盘的地址和进程虚…

Android 进程间通信机制(二) mmap 原理

一. 前言 Binder中一次拷贝的实现就是利用mmap(memory mapping)内存映射机制,我们来看看它的工作原理. 二. 参考文章 下面这几篇文章建议先好好阅读一下,都是总结的很好的文章, 每个人理解可能不一样 笔者也是看了好多博客文章和B站视频讲解, 然后加上自己的理解后 输出的一…

Linux mmap讲解

0 引言 Linux 提供了非常强大的 mmap(2) 系统调用&#xff1b; 它使开发人员能够将任何内容直接映射到进程虚拟地址空间 (VAS)。 此内容包括文件数据、硬件设备&#xff08;适配器&#xff09;内存区域&#xff0c;或只是通用内存区域。 在本文中&#xff0c;我们将只关注使用…

mmap内存映射

内存映射通信 一、mmap (memory_map) 1.1 简介 存储映射I/O (Memory-mapped I/O) 使一个磁盘文件与存储空间中的一个缓冲区相映射。于是当从缓冲区中取数据&#xff0c;就相当于读文件中的相应字节。于此类似&#xff0c;将数据存入缓冲区&#xff0c;则相应的字节就自动写入…

Linux编程之mmap示例

一、问题背景 Linux下&#xff0c;针对文件读写操作&#xff0c;一般有三个步骤&#xff1a; 1&#xff09;把文件内容读入到内存中&#xff1b;调用read&#xff08;系统调用&#xff09;&#xff0c;从内核态读取文件内容到虚拟内存&#xff1b; 2&#xff09;修改内存中的内…

【mmap】深度分析mmap:是什么 为什么 怎么用 性能总结

目录 有什么用&#xff1f; 1、文件映射 2、分配内存&#xff08;匿名文件映射&#xff09; mmap基础概念 mmap内存映射原理 mmap和常规文件操作的区别 mmap优点总结 mmap相关函数 mmap使用细节 性能总结 效率对比 有什么用&#xff1f; 将一个文件或者其它对象映射…

mmap使用

linux进程虚拟地址空间中存在一段称为mmap的内存区&#xff0c;当申请用户内存较大时&#xff0c;如大于128kb&#xff0c;系统一般会通过mmap系统调用直接映射一片内存区&#xff0c;使用结束后再通过ummap系统调用归还。关于mmap的原理网上有很多文档&#xff0c;这里不再赘述…

MMAP技术

1. mmap 基础概念 mmap 即 memory map&#xff0c;也就是内存映射。 mmap 是一种内存映射文件的方法&#xff0c;即将一个文件或者其它对象映射到进程的地址空间&#xff0c;实现文件磁盘地址和进程虚拟地址空间中一段虚拟地址的一一对映关系。实现这样的映射关系后&#xff…

mmap在嵌入式中的应用

大概雍正皇帝怎么也不会想到&#xff0c;自己在西历2022年的男生和女生眼里&#xff0c;会是截然不同的两种形象。 1 以我对身边同学朋友的观察&#xff0c;男生们大多爱看《雍正王朝》&#xff0c;他们眼中的雍正&#xff0c;大约是个推行了“火耗归公”、“摊丁入亩”等遏制…

Linux mmap原理

Linux mmap原理 前言Linux段页式内存管理mmapmmap内存映射原理文字概述mmap函数参数介绍源码解析1. 文件映射2. 缺页异常 mmap 和常规文件操作的区别mmap 使用的细节 小结 前言 mmap是linux操作系统提供给用户空间调用的内存映射函数&#xff0c;很多人仅仅只是知道可以通过mm…

Linux内存管理之mmap

目录 一. mmap系统调用 1. mmap系统调用 2. 系统调用munmap() 3. 系统调用msync() 二. 系统调用mmap()用于共享内存的两种方式&#xff1a; 三. mmap进行内存映射的原理 一. mmap系统调用 1. mmap系统调用 mmap将一个文件或者其它对象映射进内存。文件被映射到多…

Linux内核黑科技——mmap实现详解

前言&#xff1a;故事的开始是这样的&#xff0c;某天在脉脉上看到有人发了下面的帖子&#xff1a; 想不到 mmap 都成了黑科技了&#xff0c;为了让大家都能了解这个黑科技&#xff0c;所以还是写篇文章来详细介绍一下 mmap 的实现吧。 其实&#xff0c;源码分析是比较难写的&…

【Linux】Linux编程之 mmap解析

前言 虚拟内存系统通过将虚拟内存分割为称作虚拟页(Virtual Page&#xff0c;VP)大小固定的块&#xff0c;一般情况下&#xff0c;每个虚拟页的大小默认是4096字节。同样的&#xff0c;物理内存也被分割为物理页(Physical Page&#xff0c;PP)&#xff0c;也为4096字节。 一、…

讲一讲什么是 MMAP

1. mmap 基础概念 mmap 即 memory map&#xff0c;也就是内存映射。 mmap 是一种内存映射文件的方法&#xff0c;即将一个文件或者其它对象映射到进程的地址空间&#xff0c;实现文件磁盘地址和进程虚拟地址空间中一段虚拟地址的一一对映关系。实现这样的映射关系后&#xff…

人工神经网络的应用有哪些方面,人工神经网络在生活中的应用

人工神经网络的应用 人工神经网络&#xff08;Artificial Neural Network&#xff0c;简称ANN &#xff09;&#xff0c;以数学模型模拟神经元活动&#xff0c;是基于模仿大脑神经网络结构和功能而建立的一种信息处理系统。人工神经网络具有自学习、自组织、自适应以及很强的非…

人工神经网络有哪些算法,神经网络都有哪些算法

人工神经网络分类方法 从20世纪80年代末期&#xff0c;人工神经网络方法开始应用于遥感图像的自动分类。 目前&#xff0c;在遥感图像的自动分类方面&#xff0c;应用和研究比较多的人工神经网络方法主要有以下几种&#xff1a;&#xff08;1&#xff09;BP&#xff08;BackP…

深度学习-人工神经网络概述

人工神经网络 简述 很多术语听起来很唬人&#xff0c;“人工神经网络”就属于其中之一。在很多人看来&#xff0c;我们对人类的神经系统还没有研究透彻&#xff0c;这就来了一个“人工的”神经网络&#xff0c;人脑这样复杂&#xff0c;那么人工神经网络一定相当高深莫测。如果…

人工神经网络的应用实例,人工神经网络实际应用

神经网络算法实例说明有哪些&#xff1f; 在网络模型与算法研究的基础上&#xff0c;利用人工神经网络组成实际的应用系统&#xff0c;例如&#xff0c;完成某种信号处理或模式识别的功能、构作专家系统、制成机器人、复杂系统控制等等。 纵观当代新兴科学技术的发展历史&…

人工神经网络算法实战教程

神经网络&#xff08;Artificial Neural Network&#xff0c;也称为人工神经网络&#xff0c;简称ANN&#xff09;具有通过示例学习能力。ANN是受生物神经元系统启发的的信息处理模型&#xff0c;它由大量高度互联的处理元素组成&#xff0c;这些处理元素被称神经元&#xff0c…