首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

linux mmap shm

mmapshm(共享内存)是 Linux 系统中用于进程间通信(IPC)和内存管理的两种技术。

mmap(Memory Mapping)

基础概念: mmap 是一种将文件或设备映射到进程的地址空间的方法。通过 mmap,进程可以将文件的内容映射到内存中,然后像访问普通内存一样访问文件的内容。这种方式可以简化文件操作,提高 I/O 性能。

优势:

  • 减少数据拷贝次数,提高 I/O 性能。
  • 简化文件操作,可以直接通过内存指针进行读写。
  • 支持多个进程共享同一份数据。

类型:

  • 文件映射:将文件内容映射到内存。
  • 匿名映射:不与任何文件关联,常用于进程间通信。

应用场景:

  • 大文件处理,如数据库系统。
  • 进程间通信,多个进程共享数据。

shm(Shared Memory)

基础概念: 共享内存是一种进程间通信方式,允许多个进程访问同一块物理内存区域。共享内存是最快的 IPC 方式,因为它避免了数据在进程间的复制。

优势:

  • 高效:避免了数据在进程间的复制。
  • 灵活:可以用于任意大小的数据共享。

类型:

  • System V 共享内存:通过 shmgetshmat 等系统调用创建和访问。
  • POSIX 共享内存:通过 shm_openmmap 等函数创建和访问。

应用场景:

  • 需要高性能数据交换的场景,如实时数据分析。
  • 多进程协作,如并行计算。

问题解决

如果在使用 mmapshm 时遇到问题,可能的原因包括:

  • 权限问题:进程可能没有足够的权限访问共享内存或映射文件。
  • 内存不足:系统可能没有足够的物理内存或虚拟内存来创建映射。
  • 同步问题:多个进程访问共享内存时,需要适当的同步机制(如信号量)来避免竞态条件。

解决方法:

  • 检查并修改权限设置,确保进程有足够的权限。
  • 优化内存使用,关闭不必要的映射或共享内存。
  • 使用同步机制,如信号量或互斥锁,来管理对共享内存的访问。

示例代码(使用 POSIX 共享内存)

代码语言:txt
复制
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <unistd.h>

int main() {
    int shm_fd = shm_open("/my_shm", O_CREAT | O_RDWR, 0666);
    if (shm_fd == -1) {
        perror("shm_open");
        exit(1);
    }

    // 设置共享内存大小
    if (ftruncate(shm_fd, sizeof(int)) == -1) {
        perror("ftruncate");
        exit(1);
    }

    // 映射共享内存
    int *ptr = mmap(0, sizeof(int), PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0);
    if (ptr == MAP_FAILED) {
        perror("mmap");
        exit(1);
    }

    // 写入数据
    *ptr = 42;

    // 读取数据
    printf("Shared memory value: %d
", *ptr);

    // 解除映射
    if (munmap(ptr, sizeof(int)) == -1) {
        perror("munmap");
        exit(1);
    }

    // 删除共享内存
    if (shm_unlink("/my_shm") == -1) {
        perror("shm_unlink");
        exit(1);
    }

    return 0;
}

这段代码展示了如何创建、映射、使用和删除 POSIX 共享内存。在实际应用中,还需要考虑同步和错误处理等问题。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

共享内存进阶指南:深入学习mmap和shm*的用法与技巧

零拷贝有mmap和shm*接口这些方式实现。二、内存映射mmap应用程序和内核或磁盘直接数据交互,可以通过映射内存块的方式。mmap():将文件或设备映射到内存。...SHM_HUGETLB(自Linux 2.6起)使用“巨大页面”分配段。...SHM_HUGE_2MB、SHM_ HUGE _1GB(自Linux 3.8起)与SHM_HUGETLB结合使用,在支持多种HUGETLB页面大小的系统上选择可选的HUGETLB页大小(分别为2 MB和...)SHM_NORESERVE(自Linux 2.6.15起)该标志的作用与mmap() MAP_NORESERVE标志相同。...除了SHM_RND,还可以在shmflg位掩码参数中指定以下标志:标志含义SHM_EXEC(特定于Linux;自Linux 2.6.9起)允许执行段的内容。调用者必须对段具有执行权限。

38110
  • Linux mmap原理

    Linux mmap原理 前言 Linux段页式内存管理 mmap mmap内存映射原理 文字概述 mmap函数参数介绍 源码解析 1. 文件映射 2....缺页异常 mmap 和常规文件操作的区别 mmap 使用的细节 小结 ---- 前言 mmap是linux操作系统提供给用户空间调用的内存映射函数,很多人仅仅只是知道可以通过mmap完成进程间的内存共享和减少用户态到内核态的数据拷贝次数...本文想要和大家一起来聊聊mmap的原理,本文整体脉络如下: linux段页式内存管理回顾 mmap原理 ---- Linux段页式内存管理 这里的段页式内存管理主要基于linux 0.11进行讲解...(作者本人并非主攻linux,所以只是对linux 0.11略有研究) 无论是现代操作系统还是最早的linux 0.11操作系统,在对于物理内存的管理,都是将物理内存按页划分,如下图所示:...mmap的实现不是基于linux 0.11的虚拟内存管理方式,而是更复杂的方式,这里大家需要记住上面标红的那段话。

    3.7K21

    【Linux 内核 内存管理】mmap 系统调用源码分析 ① ( mmap 与 mmap2 系统调用 | Linux 内核中的 mmap 系统调用源码 )

    文章目录 一、mmap 与 mmap2 系统调用 二、Linux 内核中的 mmap 系统调用源码 一、mmap 与 mmap2 系统调用 ---- mmap 创建 " 内存映射 " 的 系统调用 有...2 种实现 , mmap 和 mmap2 ; 2 者区别是 : mmap 偏移单位是 " 字节 " , mmap2 偏移单位是 " 页 " , 但是在 arm 64 体系架构中 , 没有实现 mmap2..., 只实现了 mmap 系统调用 ; 二、Linux 内核中的 mmap 系统调用源码 ---- arm64 架构体系中 , 使用 mmap 系统调用 创建 " 内存映射 " , 调用 mmap 系统调用函数...函数 , 继续向下执行 ; mmap 系统调用代码如下 : SYSCALL_DEFINE1(old_mmap, struct mmap_arg_struct __user *, arg) { struct...>> PAGE_SHIFT); } 参考路径 : linux-4.12\mm\mmap.c#1534

    10.6K40

    【Linux 内核 内存管理】mmap 系统调用源码分析 ④ ( do_mmap 函数执行流程 | do_mmap 函数源码 )

    文章目录 一、do_mmap 函数执行流程 二、do_mmap 函数源码 调用 mmap 系统调用 , 先检查 " 偏移 " 是否是 " 内存页大小 " 的 " 整数倍 " , 如果偏移是内存页大小的整数倍..., 则调用 sys_mmap_pgoff 函数 , 继续向下执行 ; 在 sys_mmap_pgoff 系统调用函数 中 , 最后调用了 vm_mmap_pgoff 函数 , 继续向下执行 ; 在 vm_mmap_pgoff...函数 中 , 核心处理过程就是调用 do_mmap 函数 , 这是 " 内存映射 " 创建的主要函数逻辑 ; 一、do_mmap 函数执行流程 ---- do_mmap 函数 , 主要功能是 创建 "..." 内存映射 " 主要是 do_mmap 函数实现的 , 该函数定义在 Linux 内核源码的 linux-4.12\mm\mmap.c#1320 位置 ; do_mmap 函数源码如下 : /*...(flags & (MAP_POPULATE | MAP_NONBLOCK)) == MAP_POPULATE)) *populate = len; return addr; } 源码路径 : linux

    2.1K10

    Linux内存管理之mmap详解

    作者:freeboy1015 来源:http://lib.csdn.net/article/linux/62126 一. mmap系统调用 1. mmap系统调用 mmap将一个文件或者其它对象映射进内存...系统调用mmap()用于共享内存的两种方式 (1)使用普通文件提供的内存映射:适用于任何进程之间;此时,需要打开或创建一个文件,然后再调用mmap();典型调用代码如下: fd=open(name, flag...三. mmap进行内存映射的原理 mmap系统调用的最终目的是将,设备或文件映射到用户进程的虚拟地址空间,实现用户进程对文件的直接读写,这个任务可以分为以下三步: 1.在用户虚拟地址空间中寻找空闲的满足要求的一段连续的虚拟地址空间...,为映射做准备(由内核mmap系统调用完成) 每个进程拥有3G字节的用户虚存空间。...结构的成员: int (*mmap)(struct file *,struct vm_area_struct *); linux有2个方法建立页表: (1) 使用remap_pfn_range一次建立所有页表

    2.6K40

    Linux内存管理之mmap详解

    作者:freeboy1015 来源:http://lib.csdn.net/article/linux/62126 一. mmap系统调用 1. mmap系统调用 mmap将一个文件或者其它对象映射进内存...系统调用mmap()用于共享内存的两种方式 (1)使用普通文件提供的内存映射:适用于任何进程之间;此时,需要打开或创建一个文件,然后再调用mmap();典型调用代码如下: fd=open(name,...ptr=mmap(NULL, len , PROT_READ|PROT_WRITE, MAP_SHARED , fd , 0); 通过mmap()实现共享内存的通信方式有许多特点和要注意的地方 (2)使用特殊文件提供匿名内存映射...下面是struct vm_area_struct结构体的定义: #include linux/mm_types.h> /* This struct defines a memory VMM memory...结构的成员: int (*mmap)(struct file *,struct vm_area_struct *); linux有2个方法建立页表: (1) 使用remap_pfn_range一次建立所有页表

    4.5K90

    linux内存映射mmap原理分析

    mmap()会返回一个指针ptr,它指向进程逻辑地址空间中的一个地址,这样以后,进程无需再调用read或write对文件进行读写,而只需要通过ptr就能够操作文件。...()也是系统调用,如前所述,mmap()中没有进行数据拷贝,真正的数据拷贝是在缺页中断处理时进行的,由于mmap()将文件直接映射到用户空间,所以中断处理函数根据这个映射关系,直接将文件从硬盘拷贝到用户空间...图2.read系统调用原理 下面这个程序,通过read和mmap两种方法分别对硬盘上一个名为“mmap_test”的文件进行操作,文件中存有10000个整数,程序两次使用不同的方法将它们读出,加1,再写回硬盘...通过对比可以看出,read消耗的时间将近是mmap的两到三倍。...*/ gettimeofday( &tv1, NULL ); fd = open( "mmap_test", O_RDWR ); array = mmap( NULL, sizeof(int)*MAX,

    4.4K41

    Linux进程间通信:共享内存 (下)

    接Linux进程间通信:共享内存 (上) POSIX共享内存 POSIX共享内存实际上毫无新意,它本质上就是mmap对文件的共享方式映射,只不过映射的是tmpfs文件系统上的文件。 什么是tmpfs?...现在绝大多数Linux系统都有一个叫做/dev/shm的tmpfs目录,就是这样一种存在。具体使用方法,大家可以参考我的另一篇文章《Linux内存中的Cache真的能被回收么?》。...Linux提供的POSIX共享内存,实际上就是在/dev/shm下创建一个文件,并将其mmap之后映射其内存地址即可。...()"); exit(1); } /* 使用mmap将对应的tmpfs文件映射到本进程内存 */ shm_p = (int *)mmap(NULL, sizeof...要以共享方式做mmap映射,并且指定文件描述符为shmfd。 shm_unlink实际上就是unlink系统调用的封装。

    8.3K12

    【Linux 内核 内存管理】mmap 系统调用源码分析 ③ ( vm_mmap_pgoff 函数执行流程 | vm_mmap_pgoff 函数源码 )

    文章目录 一、vm_mmap_pgoff 函数执行流程 二、vm_mmap_pgoff 函数源码 调用 mmap 系统调用 , 先检查 " 偏移 " 是否是 " 内存页大小 " 的 " 整数倍 " ,...如果偏移是内存页大小的整数倍 , 则调用 sys_mmap_pgoff 函数 , 继续向下执行 ; 在 sys_mmap_pgoff 系统调用函数 中 , 最后调用了 vm_mmap_pgoff 函数..., 继续向下执行 ; 一、vm_mmap_pgoff 函数执行流程 ---- 在 vm_mmap_pgoff 函数中 , 首先 , 以 " 写者 " 身份 , 向 Linux 内核申请 读写 " 信号量...函数源码 ---- vm_mmap_pgoff 函数定义在 Linux 内核源码中的 linux-4.12\mm\util.c#296 位置 ; vm_mmap_pgoff 函数源码如下 : unsigned...(mm, &uf); if (populate) mm_populate(ret, populate); } return ret; } 源码路径 : linux-4.12\mm\util.c

    2.2K10

    【Linux】<共享内存应用>——模拟实现不同进程把hello字符对<共享内存文件对象>的放入和取出操作

    前言 大家好吖,欢迎来到 YY 滴Linux系列 ,热烈欢迎!...本章主要内容面向接触过C++ Linux的老铁 主要内容含: 一.共享内存相关与相关指令 1.共享内存 共享内存(Shared Memory)是一种允许多个进程访问同一块内存空间的机制。...例如: int shm_fd; char* ptr; shm_fd = shm_open("/my_shared_memory", O_RDWR, 0666);//O_RDWR读写 ptr = mmap...注意:编译不通过情况(linux版本过低,加上-lrt) 注:编译时如果不通过(undefined reference), 考虑LINUX版本问题 解决: 编译后面加上-lrt gcc consumer.c...; char* ptr; shm_fd = shm_open("/my_shared_memory", O_RDWR, 0666);//O_RDWR读写 ptr = mmap

    10610

    Linux 进程间通信 : 共享内存(上)

    前言 本文主要说明在Linux环境上如何使用共享内存。阅读本文可以帮你解决以下问题: 什么是共享内存和为什么要有共享内存? 如何使用mmap进行共享内存? 如何使用XSI共享内存?...所以Linux的mmap实现了一种可以在父子进程之间共享内存地址的方式,其使用方法是: 父进程将flags参数设置MAP_SHARED方式通过mmap申请一段内存。...当然这个结果在不同版本的Linux上可能是不一样的,比如在Centos 6的环境中mmap的共享内存只会记录到buff/cache中。...XSI共享内存在Linux底层的实现实际上跟mmap没有什么本质不同,只是在使用方法上有所区别。...相关的参数包括: SHM_HUGETLB (since Linux 2.6) SHM_HUGE_2MB, SHM_HUGE_1GB (since Linux 3.8) 使用大页内存的好处是提高内核对内存管理的处理效率

    11.3K33

    速通 Linux 共享内存原理

    从使用方式上讲,Linux 提供了三种共享内存的方式,包括 Unix 味的 POSIX 和 SysV 接口,还提供了直接文件映射内存的 mmap。...Golang 是通过通讯代替共享内存的优雅代表,下文仅做试验,不建议日常使用 mmap mmap 是 POSIX 规范中的文件映射内存的方法,Linux 并提供了同名系统调用。...mmap 的实现也并不复杂,众所周知 Linux 通过虚拟内存做了内存的虚拟化,进程看到的并不是实际的内存地址,要通过页表等中间层的翻译才能对物理地址进行访问,通过 VMA(vm_area_struct...和 SysV 直接操作内存段不同,POSIX 共享内存基本分为两步,一是通过 shm_open 打开一段内存(返回文件描述符),然后基于该文件描述符,通过 mmap 映射到内存中使用。...总结 从原理上讲 Linux 共享内存的主要方式只有两种,一是基于文件的 mmap,另一种就是 tmpfs,用一张图描述 Linux 几种实现共享内存的方式:

    4.1K20

    【Linux 内核 内存管理】mmap 系统调用源码分析 ⑤ ( mmap_region 函数执行流程 | mmap_region 函数源码 )

    文章目录 一、mmap_region 函数执行流程 1、检查内存申请是否合法 2、创建 " 虚拟内存区域 " 二、mmap_region 函数源码 调用 mmap 系统调用 , 先检查 " 偏移 "...; 在 do_mmap 函数中 , 调用了 mmap_region 函数 , 创建 " 虚拟内存区域 " ; 一、mmap_region 函数执行流程 ---- 1、检查内存申请是否合法 在 mmap_region...may_expand_vm(mm, vm_flags, (len >> PAGE_SHIFT) - nr_pages)) return -ENOMEM; } 源码路径 : linux-..., prev, rb_link, rb_parent); 源码路径 : linux-4.12\mm\mmap.c#1710 vma_set_page_prot(vma); 源码路径 : linux-4.12...\mm\mmap.c#1743 二、mmap_region 函数源码 ---- mmap_region 函数源码 定义在 Linux 内核源码的 linux-4.12\mm\mmap.c#1602 位置

    1.9K20
    领券