进程间通信的方式(二):共享映射区

C++实现的共享内存缓冲区 将共享内存操作封装成C++类,通过信号灯semaphore进行进程同步。可以像操作普通缓冲区那样操作共享内存,实现进程间通信 编译时需要添加-lrt编译选项 立即下载

进程间通信方式(二)

共享映射区
(一).通信方式:

进程间通信又称IPC(Inter Process Communication),它可以通过文件 管道 有名管道 共享内存 消息队列 信号量 套接字这几个方式进行通信,但是文件这种以及消息队列基本已被淘汰。
所以常用的通信方式有:
1.管道
2.信号
3.共享映射区
4.本地套接字

(二).共享映射区基本概念:

通过mmap系统调用,把普通文件映射到存储空间的一个缓冲区中,使得两个或多个进程之间可以共享这一块区域,就达到了进程间通信的目的。这种通信方式比通过文件进行通信更快,因为是直接操作缓冲区,而不是通过read以及write等函数进行操作。
这种方式可以用于父子间进程通信,也可以用于无血缘关系的进程之间通信。
当我们使用mmap建立了共享映射区之后,进行的操作就好比我们操作字符数组一样。

(三).使用共享映射区进行通信:

函数原型:void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);
所需头文件:#include <sys/mman.h>
参数含义:
1.第一个参数代表建立共享映射区在内存中的起始地址,由系统自动分配即可,所以传入NULL就行了;
2.第二个参数代表创建的映射区的大小;
3.第三个参数代表映射区的访问权限,由几个宏确定,常用的有:PROT_READ(可读),PROT_WRITE(可写),PROT_READ | PROT_WRITE(可读可写);
4.第四个参数代表标志位,常用的有:MAP_SHARED、MAP_PRIVATE、MAP_ANON,MAP_SHARED的意思是对这块映射区内容的修改会影响到被映射的文件 或者 多个进程间独享该映射区,MAP_PRIVATE的意思是对这块映射区内容的修改不会影响到被映射的文件 或者 多个进程间共享该映射区,MAP_ANON用于匿名映射;
5.第五个参数代表要映射的文件的文件描述符;
6.最后一个参数代表操作这块映射区的起始偏移量,和对数组的操作类似,不过必须是4k的整数倍。
返回值:
该函数成功调用会返回创建映射区的首地址,如果失败会返回一个宏:MAP_FAILED

由于mmap函数其实涉及到内存的分配,有了分配,自然要有释放。
释放的函数原型:int munmap(void *addr, size_t length)
头文件:#include <sys/mman.h>
参数含义:
1.第一个参数代表共享映射区的起始地址
2.第二个参数代表分配的大小
返回值:
成功返回0,失败返回-1

例子1:

#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <sys/mman.h>

int main()
{
    int len, ret;
    char *p = NULL;
    int fd = open("mytest.txt", O_CREAT | O_RDWR, 0666);  //以读写的方式打开文件,不存在则创建
    if(fd < 0)
    {
        perror("open error:");
        exit(1);
    }
    len = ftruncate(fd, 4);  //扩展文件大小
    if(len == -1)
    {
        perror("ftruncate error:");
        exit(1);
    }
    p = mmap(NULL, 4, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); //以读写的方式建立映射区
    if(p == MAP_FAILED)
    {
        perror("mmap error");
        exit(1);
    }
    strcpy(p, "abc");  //将字符串abc赋给这块映射区

    ret = munmap(p, 4);  //释放
    if(ret == -1)
    {
        perror("munmap error:");
        exit(1);
    }
    close(fd);

    return 0;
}

这个例子虽然简单,但是其实有几个需要注意的地方。
1.当我们打开一个文件的时候,操作该文件的权限是不能小于通过该文件建立映射区的权限的,即如果文件是只读的,那么映射区这边也不能进行写操作。
2.创建映射区时,包含着一次对映射文件的读操作,因为要把内容都映射到缓冲区中。所以文件的读权限应该要有才行。
3.偏移量必须是4k的整数倍。
4.munmap的第一个参数必须是映射区的首地址。

例子2:

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/wait.h>

int main()
{
    int *p;
    pid_t pid;

    //这次我们不打开文件,而是进行匿名映射。因为打开文件其实主要是起一个映射的作用,略显鸡肋,如果直接有这一块区域进行通信,那不更好
    p = (int *)mmap(NULL, 4, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0); //原本的文件描述符参数应该填-1

    if(p == MAP_FAILED)
    {
        perror("mmap error");
        exit(1);
    }

    pid = fork();
    if(pid == 0)
    {
        *p = 2;
        printf("child, *p = %d\n", *p);
    }
    else
    {
        sleep(1);
        printf("parent, *p = %d\n", *p);
        wait(NULL);

        int ret = munmap(p, 4);
        if(ret == -1)
        {
            perror("mumap error");
            exit(1);
        }
    }   
    return 0;

}

注意事项:
MAP_ANON参数只适合在linux系统中使用。

例子3:

/****************读数据******************/
#include <stdio.h>  
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <string.h>

struct STU
{
    int id;
    char name[20];
    char sex;
};

int main(int argc, char *argv[])  //argv[1]用于传递要映射的文件名
{
    int fd;
    struct STU student;
    struct STU *mm;

    fd = open(argv[1], O_RDONLY);

    mm = mmap(NULL, sizeof(student), PROT_READ, MAP_SHARED, fd, 0);  //注意这里必须是MAP_SHARED,不然数据无法共享
    if(mm == MAP_FAILED)
    {
        perror("mmap error:");
        exit(1);
    }
    close(fd);

    while(1)  //读出映射区的数据
    {
        printf("id = %d\tname = %s\t %c\n", mm->id, mm->name, mm->sex);
        sleep(2);
    }
    munmap(mm, sizeof(student));
    return 0;
}

/***************写端***************/
#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <string.h>

struct STU
{
    int id;
    char name[20];
    char sex;
};

int main(int argc, char *argv[])
{
    int fd;
    struct STU student = {10, "xiaoming", 'm'};
    char *mm;

    fd = open(argv[1], O_RDWR | O_CREAT, 0664);
    ftruncate(fd, sizeof(student));

    mm = mmap(NULL, sizeof(student), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
    if(mm == MAP_FAILED)
    {
        perror("mmap error");
        exit(1);
    }
    close(fd);

    while(1)  //写数据
    {
        memcpy(mm, &student, sizeof(student));
        student.id++;
        sleep(1);
    }
    munmap(mm, sizeof(student));
    return 0;
}

注意两个进程之间打开映射区的标志位必须是MAP_SHARED,而不是MAP_PRIVATE,否则数据无法共享。两个或多个无血缘关系的进程只要通过共享一块映射区,就可以达到通信的目的了。

ArcGIS投影变换实战:从WGS_1984到Krasovsky_1940_Albers的精准转换 本文详细解析了在ArcGIS中如何将WGS_1984地理坐标系下的数据精准转换至Krasovsky_1940_Albers投影坐标系。文章通过实战案例,重点阐述了地理坐标系与投影坐标系的区别,并逐步演示了创建自定义地理变换、使用投影栅格工具以及进行批量处理和结果验证的核心操作流程,旨在解决地图数据叠加不准的常见问题。 阅读详情

相关推荐

<工控><PLC>汇川Easy521系列PLC与汇川SV630N伺服进行EtherCat通讯的相关配置及指令编写

本系列是关于PLC相关的博文,包括PLC编程、PLC与上位机通讯、PLC与下位驱动、仪器仪表等通讯、PLC指令解析等相关内容。PLC品牌包括但不限于西门子、三菱等国外品牌,汇川、信捷等国内品牌。除了PLC为主要内容外,PLC相关元器件如触摸屏(HMI)、交换机等工控产品,如果有值得记录的内容,也会添加进来。

用沸腾的热血,支付我们的人生吧! 2万+

进程通信方式---共享映射区(无血缘关系用的)

原理:共享映射区是将文件内容映射到进程的地址空间中,使得多个进程可以通过访问这个共享的内存区域来实现通信。进程对映射区域的操作就如同对文件进行操作一样,这些操作会直接反映在文件和其他共享该映射区域的进程中。示例场景:多个进程需要共同操作一个配置文件,通过将该配置文件映射到共享映射区,进程可以直接在内存中读取和修改配置信息,而不需要频繁地进行文件 I/O 操作。优点:结合了内存操作的高效性和文件存储的持久性;可以方便地在不相关的进程之间实现通信,只要它们能访问到同一个文件。缺点。

m0_74795952的博客 1280

dbt+Snowflake实战:数据建模、权限隔离与性能优化全指南

dbt(data build tool)作为现代数据栈的核心建模工具,其与Snowflake的深度协同远不止于SQL编译执行——它本质是将软件工程实践(如版本控制、测试驱动、CI/CD)注入数据交付流程。理解dbt的声明式建模原理与Snowflake的虚拟仓库、Time Travel、TRANSIENT表、聚簇键等底层机制如何咬合,是实现可维护、可审计、低成本数据产品交付的关键。本文聚焦dbt在Snowflake环境中的真实落地挑战,涵盖schema与warehouse的物理映射设计、role级硬隔离策略、

weixin_34389926的博客 312

共享存储映射

存储映射I/O 存储映射I/O(memory-mapped I/O)使一个磁盘文件与存储空间中的一个缓冲区相映射。于是当从缓冲区中获取数据,就相当于读文件中的相应字节。与此类似,将数据存入缓冲区,则相应的字节就自动写入文件。这样,就可在不适用read和write函数的情况下,使用地址(指针)完成I/O操作。 使用这种方法,首先应通知内核,将一个指定文件映射到储存区域中。这个映射工作可以通过mmap...

qq_42265158的博客 424

从零开始做题:big_zip

内容为:You_know_the_bed_feels_warmer_Sleeping_here_alone_You_know_I_dream_in_color_And_do_the_things_I_want_You_think_you_got_the_best_of_me_Think_you_had_the_last_laugh_Bet_you_think_that_everything_good_is_gone。查看压缩包内容,发现有五字节长度的文件,用crc碰撞攻击破解明文。

weixin_44626085的博客 1241

Windows server 2012R2安装Oracle11g

打开 开始——所有程序——Oracle-OraDb11g_home1——配置和移植工具——Database Configuration Assistant。打开 开始——所有程序——Oracle-OraDb11g_home1——配置和移植工具——Net Configuration Assistant。首先打开Oracle的安装位置找到下面的位置找到tnsnames.ora文件右键编辑。打开Oracle的安装位置找到下面的位置找到tnsnames.ora文件右键编辑。选择仅安装数据库软件。

qq_74770105的博客 3596

进程通信的三种方式(管道、消息缓冲队列、共享缓冲区)

管道: 消息缓冲队列: 共享缓冲区:

Cheney ' blog 8676

阿里巴巴达摩院人工智能训练师(高级)

阿里巴巴达摩院人工智能训练师(高级)

huang0612123的博客 1万+

共享内存区—内存映射(文件映射)

1 内存映射作用 2 mmap映射 3 munmap从进程的地址空间删除一个映射关系 4 msync同步 5 匿名内存映射 通过void *mmap(void *addr, size_t len, int prot, int flags, int fd, off_t offset)映射函数中的fd参数可以看出一般内存映射是将一个文件映射到内存区,我们也可以不使用文件来创建一个匿名内存映射,这样可以更简单的提供一个例如供父子进程共享的一个内存区域(子进程创建后不共享父进程的地址空间,各自有各自的地

chengcheng1024的博客 2455

LeRobot 入门教程(十四)Meta-World 机器人多任务与元强化学习操作仿真基准平台

Meta-World是一个开源机器人操作模拟基准平台,专注于多任务与元强化学习研究。该平台提供50项多样化任务(MT50套件),采用标准化评估协议测试算法泛化能力。LeRobot平台支持Meta-World任务评估,提供预处理数据集和训练工具。用户可通过命令行快速训练SmolVLA策略,并评估模型在简单、中等、困难等不同难度任务上的表现。文章还提供了兼容性问题和实用技巧建议,如使用完整MT50任务集测试泛化能力、采用one-hot任务条件化等。这些资源为研究人员开展机器人多任务学习提供了标准化实验环境。

2506_90492529的博客 1019

《Autosar_BSW高阶配置》总目录_培训教程持续更新中...

目录 一、Autosar COM Module 二、Autosar BswM Module 三、Autosar EcuM Module 四、Autosar DCM Module 五、Autosar DEM Module 六、其它Module陆续推出 欢迎大家订阅《Autosar_BSW高阶配置》专栏(可以理解为是Autosar培训教程),该专栏每周至少更新一篇,一次订阅,不再二次收费,献上常用的案例和配置方法。下方整理了相关博文的链接(单击蓝色字体即可跳转),方便大家获取。 本专栏...

「汽车电子助手」的博客 4万+

mmap映射区和shm共享内存的区别总结

linux中的两种共享内存。一种是我们的IPC通信System V版本的共享内存,另外的一种就是我们今天提到的存储映射I/O(mmap函数) 在说mmap之前我们先说一下普通的读写文件的原理,进程调用read或是write后会陷入内核,因为这两个函数都是系统调用,进入系统调用后,内核开始读写文件,假设内核在读取文件,内核首先把文件读入自己的内核空间,读完之后进程在内核回归用户态,内核把读入内核内存的数据再copy进入进程的用户态内存空间。实际上我们同一份文件内容相当于读了两次,先读入内核空间,再从内核空间

modi000的博客 826

YOLOv改进 | YOLOv11更换主干Backbone之MobileNetV2(轻量化主干网络结构--高效轻量移动模型)

本文提出将YOLOv11的主干网络替换为轻量化的MobileNetV2,以提升模型在移动端设备的部署效率。MobileNetV2通过倒残差结构和线性瓶颈层,显著减少了计算量和参数量(降至1M~3M),同时保持多尺度特征提取能力。实验表明,改进后的模型在移动设备上可实现20-30 FPS的实时检测,适用于手机APP、无人机和工业监控等场景。核心代码展示了倒残差块的实现,通过深度可分离卷积和通道扩展/压缩实现高效特征提取。

走向CTO的路上... 1461

windows XP,ReactOS系统3.4 共享映射区(Section)---1

系列文章目录 文章目录系列文章目录3.4 共享映射区(Section)NtCreateSection ()MmCreateSection ()MmCreateDataFileSection()NtMapViewOfSection()MmNotPresentFaultSectionView() 3.4 共享映射区(Section) 对于用户空间的映射,一个物理页面通常只属于一个进程,即只被映射到一个进程的用户空间,因而其页面号只出现在一个进程的页面映射表中。注意这里说的是用户空间,至于系统空间的页面则本来就

zhyjhacker的博客 1363

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

各种进程间通信方式详解,多的不说了大家自己看吧

各种进程间通信方式详解 文章目录各种进程间通信方式详解1.基本原理2.基本概念1.进程间通信的重要性2.IPC 方式分类汇总1.基于内核的通信共享内存和共享映射区的区别2.基于文件系统的通信原理3.基于网络的通信原理(适用于不同主机上的进程通信)3.管道(使用最简单)1.概述2.使用3.管道的读写行为1.读管道2.写管道3.练习1.管道实现 ls|wc-l2.管道实现兄弟进程通信3.测试管道是否允许一个pipe有一个写端多个读端?有一个读端多个写端?4.管道大小5.管道优劣6.有名管道FIFO实现没有血缘关

m0_74795952的博客 1059

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

Linux进程间通信——内存共享映射

一、概念 什么是内存共享映射? 将磁盘文件的一部分直接映射到内存中 共享内存,就是两个或多个进程都可以访问的同一块内存空间,一个进程对这块空间内容的修改可为其他参与通信的进程所看到的 映射种类 共享映射(share),内存中数据修改时,磁盘对应也同时修改 私有映射(private),内存中数据修改时,磁盘不修改 内存共享特点 实现进程间通信最简单也是最直接的方法就是共享内存——为参与通信...

赵小厨的博客 564

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

Linux系统应用编程---进程间通信(二)【内存共享映射mmap】

参考链接: https://blog.youkuaiyun.com/qq_44361695/article/details/99075993 https://segmentfault.com/a/1190000014616732 http://www.cppblog.com/jerryma/archive/2011/08/02/152279.html 1. 内存共享映射的概念 mmap的作用就是把磁盘文件的一部分直接映射到进程的内存中,那么进程就可以直接对该内存文件进行操作。 mmap也设置了两种...

M2嵌入式 549

Linux线程通信之共享映射区

IPC方法(InterProcess Communication) Linux环境下,进程地址空间相互独立,每个进程各自有不同的用户地址空间。任何一个进程的全局变量在另一个进程中都看不到,所以进程和进程之间不能相互访问,要交换数据必须通过内核,在内核中开辟一块缓冲区,进程1把数据从用户空间拷到内核缓冲区,进程2再从内核缓冲区中把数据读走,内核提供的这种机制称为进程间通信 在进程间完成数据传递需要借助os提供的特殊方法,如:文件、管道、信号、共享内存、消息队列、套接字、命名管道等。 现如今常用的

qq_41033011的博客 496

Liunx操作-Record20—MMAP共享映射区相关的操作

MMAP共享映射区相关的操作

恋蛩音的博客 490

Linux C/C++编程之(十七)进程间通信

文章目录一、概述 一、概述

种树最好的时间是10年前,其次是现在!!! 9221

windows修改内存读写权限_Linux进程间通信——内存共享映射

一、概念什么是内存共享映射?将磁盘文件的一部分直接映射到内存中共享内存,就是两个或多个进程都可以访问的同一块内存空间,一个进程对这块空间内容的修改可为其他参与通信的进程所看到的映射种类共享映射(share),内存中数据修改时,磁盘对应也同时修改私有映射(private),内存中数据修改时,磁盘不修改内存共享特点实现进程间通信最简单也是最直接的方法就是共享内存——为参与通信的多个进程在内存中开辟一个...

weixin_39996798的博客 399

进程间通信(IPC)

1、创建映射区的过程中,隐含着一次对映射文件的【读操作】2、当MAP_SHARED映射区的权限应该

BSY丶的博客 1163

Linux系统编程-进程间通信-管道、信号、共享映射区

Linux 内核编程-IPC进程间通信 进程间通信模式 管道 信号 信号量 共享映射区 (共享内存) 套接字 文件 消息队列 进程间通信的本质是需要借助内核的 a 进程把数据从用户空间拷贝到内核空间 b 进程把数据从内核空间拷贝到用户空间 一般的进程间通信需要拷贝两次内存,除了 mmap, binder驱动需要拷贝一次 管道 使用简单 无名管道 半双工通信 (只有向一个方向流) 管道可以简单理解为一种特殊的文件形式,可以用文件的读写方法,不是一种简单的文件,只会占用内存 管道.

好好学习,天天向上 191

音视频:06.linux系统-IPC进程间通信

linux系统-IPC进程间通信1.进程间通信的方式2.管道(pipe)3.共享映射区4.信号 1.进程间通信的方式 文件,管道,信号、信号量,共享映射区(共享内存),消息队列,管道,套接字(socket) 着重讲下: 管道(使用简单) 信号(开销比较小) 共享映射区 套接字(低速稳定) 一般都是通过内核共享空间进行通信 2.管道(pipe) 无名管道,半双工的通信方式(数据流向固定:只能 a 的数据写给 b ,或者 b 的数据写给 a ) 管道大家可以简单的理解为一种特殊的文件形式,我们可以用

东方升起代码的博客 311

Linux的内存共享映射(mmap和munmap)

Linux下的进程间通信也可以使用mmap的内存共享映射来实现,mmap的作用就是把磁盘文件的一部分直接映射到进程的内存中,那么进程就可以直接对该内存文件进行操作,mmap也设置了两种机制:共享和私有, ...

Charles_Zaqdt的博客 901

Linux进程间通信的方式

IPC方法 Linux环境下,进程地址空间相互独立,每个进程各自有不同的用户地址空间。任何一个进程的全局变量在另一个进程中都看不到,所以进程和进程之间不能相互访问,要交换数据必须通过内核,在内核中开辟一块缓冲区,进程1把数据从用户空间拷到内核缓冲区,进程2再从内核缓冲区把数据读走,内核提供的这种机制称为进程间通信(IPC,InterProcess Communication)。 在进程间完成数据传递需要借助操作系统提供特殊的方法,如:文件、管道、信号、共享内存、消息队列、套接字、命名管道等。常用的进

baidu_15952103的博客 196
上一篇: 进程间通信的方式(一):管道
下一篇: Sicp第1章学习总结
UKey_
博客等级 码龄10年 258粉丝 186原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值