Linux 共享内存mmap,进程通信

文章目录

  • 前言
  • 一、存储映射 I/O
  • 二、mmap, munmap
  • 三、父子进程间 mmap 通信
  • 四、非血缘关系进程间 mmap 提通信
  • 五、mmap 匿名映射区
  • 总结

前言

进程间通信是操作系统中重要的概念之一,使得不同的进程可以相互交换数据和进行协作。其中,共享内存是一种高效的进程间通信机制,而内存映射(mmap)是实现共享内存的一种常见方法。


一、存储映射 I/O

存储映射 I/O 是 一个磁盘文件 与 存储空间中的一个缓冲区相映射。于是, 当从缓冲区中取数据,就相当于读文件中的相应字节。于此类似,将数据存入缓冲区,则相应的字节就自动写入文件。这样, 就可在 不适用 read 和 write 函数的情况下,使用 地址(指针)完成 i/o 操作。

使用这种方法,首先应通知内核,将一个指定文件映射到存储区域中。这个映射工作可以通过 mmap 函数来实现。使用 mmap 系统调用,进程可以直接操作共享内存的指针,而不需要复杂的数据结构和同步机制。
在这里插入图片描述

理解 共享内存
共享内存是一种特殊的内存区域,它可以被多个进程访问和操作。这意味着不同的进程可以直接读取或写入该共享内存区域中的数据。相比于其他进程间通信机制,共享内存具有较低的开销和高效的数据传输速度。


二、mmap, munmap

mmap 用于创建共享内存映射。munmap 用来 释放内存。

 #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. void * mmap ( void * addr, size_t length , int prot , int flags , int fd , off_t offset ) ;

参数:

  • addr : 指定映射区的首地址。通常传 NULL / 0,表示让系统自动分配。
  • length :共享映射区的大小。
  • prot : 共享映射区的读写属性。
  • flags : 标注共享内存的共享属性。
  • fd :用于创建共享映射区的哪个文件的,文件描述符。
  • offset :

返回值:
在这里插入图片描述

  • 成功 : 映射区的首地址。
  • 失败 : 返回 M AP_FAILED。
  1. int munmap ( void * addr , size_t length ) ;
    在这里插入图片描述

三、父子进程间 mmap 通信

void sys_error(const char *str)
{perror(str);		exit(1);									// 正常退出程序
}int var = 10;int main(void)
{int fd;char *p;pid_t pid;fd = open("1.txt", O_RDWR);if(fd < 0){sys_error("open error");}ftruncate(fd,100);								// 扩展空间大小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("map error!");}close(fd);pid = fork();								 // 创建子进程if(pid == 0){strcpy(p,"This is child");var = 100;printf("%s, Child: var = %d\n",p, var);}else{sleep(1);printf("Parent: %s,var = %d\n",p,var);}wait(NULL);											// 回收子进程munmap(p, len);										// 释放映射区return 0;
}

在这里插入图片描述
var 是 全局变量,父子进程操作 全局变量时,读数据时 共享; 写数据时 复制。
上述代码中,子进程写数据时,是复制一份数据 后 对复制的数据进程修改。父进程 读数据时,全局变量还是原本的数值。

四、非血缘关系进程间 mmap 提通信

1.c 不断写数据:

void sys_error(const char *str)
{perror(str);		exit(1);
}int main(void)
{int fd;char *p;int i = 0;fd = open("1.txt", O_RDWR);if(fd < 0){sys_error("open error");}ftruncate(fd,100);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("map error!");}close(fd);while(1){sleep(1);*p = i;								// 不断写入数据i++;}munmap(p, len);return 0;
}

2.c 不断读数据

void sys_error(const char *str)
{perror(str);		exit(1);
}int main(void)
{int fd;char *p;int i = 0;fd = open("1.txt", O_RDWR);if(fd < 0){sys_error("open error");}ftruncate(fd,100);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("map error!");}close(fd);while(1){sleep(1);printf("*p = %d\n",*p);				// 不断读数据}munmap(p, len);return 0;
}

在这里插入图片描述

五、mmap 匿名映射区

mmap 匿名映射区是在进程的虚拟内存空间中创建的一段没有对应物理文件的内存区域。它通常用于进程间通信和临时存储数据,不需要使用文件作为映射源。匿名映射区在 Linux 系统中非常常见。

在使用mmap系统调用创建匿名映射区时,传递给mmap函数的文件描述符参数(通常为-1)表明不会有一个与之相关联的文件。
mmap 函数的 参数二,可以为指定的大小。参数四 为 MAP_SHARED|MAP_ANONYMOUS

void sys_error(const char *str)
{perror(str);		exit(1);									// 正常退出程序
}int var = 10;int main(void)
{char *p;pid_t pid;p = mmap(NULL, 20, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0);		// 创建共享映射区if(p == MAP_FAILED){sys_error("map error!");}pid = fork();								 // 创建子进程if(pid == 0){strcpy(p,"This is child");var = 100;printf("%s, Child: var = %d\n",p, var);}else{sleep(1);printf("Parent: %s,var = %d\n",p,var);}wait(NULL);											// 回收子进程munmap(p, 20);										// 释放映射区return 0;
}

总结

进程间共享内存映射(mmap)通信是一种高效、灵活的进程间通信机制。通过内存映射,不同的进程可以共享相同的数据区域,提高数据访问速度和性能。然而,在使用该机制时需要注意同步机制、内存管理和安全性等问题,以确保共享数据的正确性和安全性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/32821.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

非关系型数据库---Redis安装与基本使用

一、数据库类型 关系数据库管理系统&#xff08;RDBMS&#xff09;非关系数据库管理系统&#xff08;NoSQL&#xff09; 按照预先设置的组织机构&#xff0c;将数据存储在物理介质上(即&#xff1a;硬盘上) 数据之间可以做无关联操作 (例如: 多表查询&#xff0c;嵌套查询&am…

详细记录Pycharm配置已安装好的Conda虚拟环境

当安装好conda环境之后&#xff0c;想要在Pycharm中使用&#xff0c;那么就要在Pycharm中导入&#xff0c;我这里使用的pycharm-professional-2023.2这个版本&#xff0c;下面是详细步骤&#xff1a; 1.打开File->Settings&#xff1a; 2.找到Project——>Python Inter…

【每日一题】1572. 矩阵对角线元素的和

【每日一题】1572. 矩阵对角线元素的和 1572. 矩阵对角线元素的和题目描述解题思路 1572. 矩阵对角线元素的和 题目描述 给你一个正方形矩阵 mat&#xff0c;请你返回矩阵对角线元素的和。 请你返回在矩阵主对角线上的元素和副对角线上且不在主对角线上元素的和。 示例 1&a…

基于Gradio的GPT聊天程序

网上很多别人写的&#xff0c;要用账号也不放心。就自己写了一个基于gradio的聊天界面&#xff0c;部署后可以本地运行。 特点&#xff1a; 可以用openai的&#xff0c;也可以用api2d&#xff0c;其他api可以自己测试一下。使用了langchain的库 可以更改模型&#xff0c;会的…

【调整奇数偶数顺序】

调整奇数偶数顺序 1.题目 输入一个整数数组&#xff0c;实现一个函数&#xff0c; 来调整该数组中数字的顺序使得数组中所有的奇数位于数组的前半部分&#xff0c; 所有偶数位于数组的后半部分。 2.题目分析 这道题首先用到的方法是冒泡排序的思想&#xff0c;首先通过冒泡排序…

时序预测 | MATLAB实现BO-BiLSTM贝叶斯优化双向长短期记忆神经网络时间序列预测

时序预测 | MATLAB实现BO-BiLSTM贝叶斯优化双向长短期记忆神经网络时间序列预测 目录 时序预测 | MATLAB实现BO-BiLSTM贝叶斯优化双向长短期记忆神经网络时间序列预测效果一览基本介绍模型搭建程序设计参考资料 效果一览 基本介绍 MATLAB实现BO-BiLSTM贝叶斯优化双向长短期记忆…

Linux下C语言调用libcurl库获取天气预报信息

一、概述 当前文章介绍如何在Linux&#xff08;Ubuntu&#xff09;下使用C语言调用libcurl库获取天气预报的方法。通过HTTP GET请求访问百度天气API&#xff0c;并解析返回的JSON数据&#xff0c;可以获取指定城市未来7天的天气预报信息。 二、设计思路 【1】使用libcurl库进…

用MariaDB创建数据库,SQL练习,MarialDB安装和使用

前言&#xff1a;MariaDB数据库管理系统是MySQL的一个分支&#xff0c;主要由开源社区在维护&#xff0c;采用GPL授权许可 MariaDB的目的是完全兼容MySQL&#xff0c;包括API和命令行&#xff0c;使之能轻松成为MySQL的代替品。在存储引擎方面&#xff0c;使用XtraDB来代替MySQ…

Electron+vue3项目使用SQLite3数据库

SQLite 是一个进程内的库&#xff0c;实现了自给自足的、无服务器的、零配置的、事务性的 SQL 数据库引擎。它是一个零配置的数据库&#xff0c;这意味着与其他数据库不一样&#xff0c;我们不需要在系统中配置。 就像其他数据库&#xff0c;SQLite 引擎不是一个独立的进程&am…

Scratch 之 如何矢量图中去除矢量刺

如果您曾经在“矢量编辑器”中使用过轮廓&#xff0c;那么您一定已经看到了这一点... 这被称为矢量刺&#xff0c;只有当你正在绘制的形状中有尖锐的点或角时才会发生这种情况&#xff0c;这真的很烦人&#x1f621; 所以在这个视频中&#xff0c;我将向你展示如何摆脱这些令人…

Springboot后端通过路径映射获取本机图片资源

项目场景&#xff1a; 项目中对图片的处理与查看是必不可少的&#xff0c;本文将讲解如何通过项目路径来获取到本机电脑的图片资源 如图所示&#xff0c;在我的本机D盘的图片测试文件夹(文件夹名字不要有中文)下有一些图片&#xff0c; 我们要在浏览器上访问到这些图片&#…

在时间和频率域中准确地测量太阳黑子活动及使用信号处理工具箱(TM)生成广泛的波形,如正弦波、方波等研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

python压缩pdf文件大小

pdf文件过大&#xff0c;经常会是一个问题&#xff0c;但是市面上基本上都是收费的工具&#xff0c;wps需要开会员才能使用。因此找了一个python库进行试验&#xff1a; 首先需要安装 pip install aspose-pdf 运行的代码&#xff1a; import aspose.pdf as apcompressPdfDo…

你的服务器安全吗?--服务器防渗透

1、概述 在本人所处的公司的服务器正式遭到黑客攻击之前&#xff0c;一直都以为 黑客 是个遥不可及的词&#xff0c;直到真正成为了受害者时&#xff0c;才猛然意识到安全的重要性。有一些基本经验和心得总结出来&#xff0c;和同行分享一下吧。 2、暴破手段 最粗暴的黑客行为…

什么是敏捷开发?

敏捷开发流程&#xff1a;制度化、规范化地PUA程序员的顶级神器&#xff01;&#xff01;&#xff01;

SQL | 使用函数处理数据

8-使用函数处理数据 8.1-函数 SQL可以用函数来处理数据。函数一般是在数据上执行的&#xff0c;为数据的转换和处理提供了方便。 8.1.1 函数带来的问题 每种DBMS都有特定的函数&#xff0c;只有很少一部分函数&#xff0c;是被所有主要的DBMS等同的支持。 虽然所有的类型的…

【C++】C++异常

文章目录 1. C语言传统处理错误的方式2. C异常的概念3. 异常的使用3.1 异常的抛出和捕获3.2 异常的重新抛出3.3 异常安全3.4 异常规范 4. C标准库的异常体系5. 自定义的异常体系6. 异常的优缺点 1. C语言传统处理错误的方式 C语言传统的错误处理机制有两个&#xff1a; 终止程…

v-md-editor自定义锚点(生成目录)数组转树结构

接前两篇博文&#xff0c;最终方案终于定了&#xff0c;也把之前做的编辑器模式给否决了&#xff0c;原因是系统中有老的文档需要平替&#xff0c;因此就不能通过编辑器这种模式了&#xff0c;太麻烦了。 最终方案&#xff1a;线下手动pandoc word转markdown&#xff0c;然后将…

使用Java根据表名导出与导入Sql

前言 很粗糙啊&#xff0c;有很多可以优化的地方&#xff0c;而且也不安全&#xff0c;但是临时用还是OK的&#xff0c;我这个是公司里面的单机软件&#xff0c;不联网。 嗨&#xff01;我是一名社交媒体增长黑客&#xff0c;很高兴能帮助您优化和丰富关于批量作业导出和导入…

pycharm离线安装依赖包

一、对于单个下载离线包&#xff0c;然后安装 1、先去https://pypi.org/网站下载离线包&#xff0c;下载到本地&#xff1b; 2、从磁盘中找到刚刚下载包&#xff0c;点击确定就可以安装了 二、将本地项目所有依赖包全部下载下来&#xff0c;然后批量在另一个项目&#xff…