Linux使用mmap调用创建、读写和释放共享内存区域

 更新时间:2025年11月26日 09:02:31   作者:郝学胜-神的一滴  
共享内存是Linux系统中一种高效的进程间通信(IPC)机制,允许多个进程访问同一块物理内存区域,在所有IPC机制中,共享内存是最快的一种,因为它避免了数据在内核空间和用户空间之间的复制,本文将详细介绍如何使用mmap系统调用创建、读写和释放共享内存区域

1. 使用mmap创建映射区

mmap(memory map)是Linux系统提供的一个系统调用,用于将文件或设备映射到进程的地址空间。它也可以用于创建匿名映射区域,实现进程间的共享内存。

mmap函数原型

#include <sys/mman.h>
void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);

参数说明:

  • addr:指定映射区的起始地址,通常设为NULL,让系统自动选择合适的地址
  • length:映射区域的大小
  • prot:映射区域的保护标志,如PROT_READ(可读)、PROT_WRITE(可写)、PROT_EXEC(可执行)等
  • flags:映射类型标志,如MAP_SHARED(共享)、MAP_PRIVATE(私有)等
  • fd:文件描述符,对于匿名映射设为-1
  • offset:文件映射的偏移量,通常设为0

使用mmap创建共享内存的步骤

  1. 打开或创建一个文件(对于文件映射)或使用匿名映射
  2. 调用mmap函数创建映射区
  3. 检查mmap的返回值,确保映射成功

示例代码:使用mmap创建匿名共享内存

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

int main() {
    // 定义映射区域大小
    size_t size = 4096;
    
    // 使用mmap创建匿名共享内存
    void *mapped = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
    
    // 检查映射是否成功
    if (mapped == MAP_FAILED) {
        perror("mmap failed");
        return 1;
    }
    
    printf("Memory mapped at address %p\n", mapped);
    
    // 使用共享内存...
    
    // 释放映射区
    if (munmap(mapped, size) == -1) {
        perror("munmap failed");
        return 1;
    }
    
    return 0;
}

2. 读写映射区

一旦成功创建了映射区,进程就可以像操作普通内存一样读写该区域。需要注意的是,如果映射的是文件,对映射区的修改会反映到实际文件中(当使用MAP_SHARED标志时)。

读写映射区的注意事项

  1. 对于文件映射,修改的内容会在适当的时机写回文件(取决于系统实现)
  2. 多个进程同时访问共享内存时需要同步机制,如信号量、互斥锁等
  3. 不要越界访问映射区域,可能导致段错误

示例代码:读写映射区

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

int main() {
    // 定义映射区域大小
    size_t size = 4096;
    
    // 使用mmap创建匿名共享内存
    void *mapped = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
    
    // 检查映射是否成功
    if (mapped == MAP_FAILED) {
        perror("mmap failed");
        return 1;
    }
    
    // 写入数据到映射区
    char *message = "Hello, shared memory!";
    strncpy((char *)mapped, message, strlen(message));
    
    // 读取并打印映射区内容
    printf("Read from shared memory: %s\n", (char *)mapped);
    
    // 释放映射区
    if (munmap(mapped, size) == -1) {
        perror("munmap failed");
        return 1;
    }
    
    return 0;
}

3. 使用munmap释放映射区

当进程不再需要使用映射区时,应该调用munmap函数释放该区域,释放的内存可以被系统重新分配。

munmap函数原型

#include <sys/mman.h>
int munmap(void *addr, size_t length);

参数说明:

  • addr:要释放的映射区的起始地址,必须是mmap返回的地址
  • length:要释放的区域大小,必须与mmap调用时的length参数相同

使用munmap的注意事项

  1. 确保传入正确的地址和大小
  2. 不要重复释放同一个映射区
  3. 释放映射区后,不应该再访问该区域的内存

示例代码:使用munmap释放映射区

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

int main() {
    // 定义映射区域大小
    size_t size = 4096;
    
    // 使用mmap创建匿名共享内存
    void *mapped = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
    
    // 检查映射是否成功
    if (mapped == MAP_FAILED) {
        perror("mmap failed");
        return 1;
    }
    
    // 使用共享内存...
    
    // 释放映射区
    if (munmap(mapped, size) == -1) {
        perror("munmap failed");
        return 1;
    }
    
    printf("Memory unmapped successfully\n");
    return 0;
}

4. mmap的优缺点

优点

  1. 高效:共享内存是最快的IPC机制,因为数据不需要在内核和用户空间之间复制
  2. 灵活:可以映射文件或创建匿名共享内存
  3. 可以与文件系统结合使用,实现数据持久化

缺点

  1. 需要额外的同步机制:多个进程同时访问共享内存时需要同步
  2. 管理复杂:需要手动管理映射区的创建和释放
  3. 安全性较低:共享内存对所有具有访问权限的进程可见

5. 实际应用场景

  1. 大数据处理:多个进程共享处理大数据集
  2. 实时系统:需要低延迟数据交换的系统
  3. 数据库系统:多个进程共享数据缓存
  4. 图形处理:多个进程共享图像数据

6. 总结

mmap是Linux中实现共享内存的重要工具,它提供了一种高效的方式让多个进程共享内存区域。通过合理使用mmap、munmap以及适当的同步机制,可以实现高效的进程间通信。在实际应用中,需要根据具体需求选择合适的IPC机制,并在性能、安全性和复杂性之间做出权衡。

以上就是Linux使用mmap调用创建、读写和释放共享内存区域的详细内容,更多关于Linux mmap操作共享内存区域的资料请关注脚本之家其它相关文章!

相关文章

  • Linux pgrep命令使用及说明

    Linux pgrep命令使用及说明

    pgrep是一个用于根据名称查找进程ID的命令,返回的是进程ID,它可以与ps等命令配合使用,常用参数包括-l、-a、-c等,与其他命令配合时,需要使用xargs传递参数
    2025-11-11
  • 详解Linux获取线程的PID(TID、LWP)的几种方式

    详解Linux获取线程的PID(TID、LWP)的几种方式

    这篇文章主要介绍了详解Linux获取线程的PID(TID、LWP)的几种方式,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-05-05
  • Linux 服务器上配置基于SSH 密钥的身份验证及使用方法

    Linux 服务器上配置基于SSH 密钥的身份验证及使用方法

    SSH是一种加密协议,用于管理和与服务器通信,在使用 Linux 服务器时,您经常会花费大量时间在通过 SSH 连接到服务器的终端会话中,这篇文章主要介绍了Linux 服务器上配置基于SSH 密钥的身份验证及使用方法,需要的朋友可以参考下
    2024-04-04
  • CentOS 7.2安装Nginx 1.10.2的详细教程

    CentOS 7.2安装Nginx 1.10.2的详细教程

    最近公司要切换VPS,所以打算使用最新的系统进行搭建LNMP,这篇文章是为CentOS 7.2安装Nginx 1.10.2的安装记录,记录下以便下次或者有需要的朋友们参考使用。下面跟着小编来一起学习学习吧。
    2016-11-11
  • linux下安装nodejs的详细步骤

    linux下安装nodejs的详细步骤

    本篇文章主要介绍了linux下安装nodejs的详细步骤,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-06-06
  • Linux 6 修改ssh默认远程端口号的操作步骤

    Linux 6 修改ssh默认远程端口号的操作步骤

    这篇文章主要介绍了Linux 6 修改ssh默认远程端口号的操作步骤,本文给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
    2019-09-09
  • centos6.5下svn的使用说明

    centos6.5下svn的使用说明

    这篇文章主要介绍了centos6.5下svn的使用说明的相关资料,方法非常的实用,有需要的小伙伴可以参考下
    2016-10-10
  • Apache HTTP 服务器的安全配置指南(最新推荐)

    Apache HTTP 服务器的安全配置指南(最新推荐)

    Apache作为最广泛使用的Web服务器之一,其安全配置至关重要,本文将探讨如何通过一系列措施加强Apache的安全性,包括配置SSL/TLS、设置访问控制、防止常见攻击等,感兴趣的朋友一起看看吧
    2024-12-12
  • Linux Autofs自动挂载服务安装部署教程

    Linux Autofs自动挂载服务安装部署教程

    大家好,本篇文章主要讲的是Linux Autofs自动挂载服务安装部署教程,感兴趣的同学赶快来看一看吧,对你有帮助的话记得收藏一下哦
    2021-11-11
  • windows下安装PEAR php5.3.1下解决出错的方法

    windows下安装PEAR php5.3.1下解决出错的方法

    在配置好了Apache2.2.14和PHP5.3.1后,最近想安装PEAR(PHP Extension and Application Repository),但是在执行批处理文件go-pear.bat的时候出现了错误
    2010-02-02

最新评论