迹忆客 专注技术分享

当前位置:主页 > 学无止境 > 编程语言 > C语言 >

C语言使用mmap函数写入内存

作者:迹忆客 最近更新:2023/05/05 浏览次数:

在本文中,我们将学习 mmap() 函数,它需要多少个参数,以及如何在 C 编程中使用 mmap() 写入内存。


C 中的 mmap() 函数

我们使用这个函数来映射进程地址空间和设备或文件。 mmap() 函数请求内存 n 字节的可写匿名和私有映射。

匿名映射和私有映射意味着它不受文件支持,也不与其他进程共享。 要使用 mmap(),我们必须包含头文件。

#include <sys/mman.h>
It takes six arguments:

void * mmap (
    void *address,
    size_t length,
    int protect,
    int flags,
    int filedes,
    off_t offset
)

在开始使用这个函数之前,让我们讨论一下参数。

  1. address - 它提供用于映射的首选起始地址。 如果没有其他映射,内核将选择附近的页面边界,创建一个映射。

    否则,内核将选择新地址。 如果此参数的值为 NULL,则内核会将映射放置在它认为合适的位置。

  2. length - 映射的字节数。
  3. protect - 它控制允许什么类型的访问。 例如,用于读访问的 PROT_READ,用于写访问的 PROT_WRITE,以及用于执行的 PROT_EXEC。
  4. flags - 用于控制地图的性质。 下面列出了一些常见和有用的标志:
    • MAP_SHARED - 与其他进程共享映射。
    • MAP_FIXED - 系统被迫使用通过地址参数给出的相同映射地址。
    • MAP_ANONYMOUS / MAP_ANON - 它创建匿名映射。
    • MAP_PRIVATE - 映射将是私有的,并且在使用此标志时对其他人不可见。
  1. filedes - 应该映射文件描述符。
  2. offset - 文件映射从这个偏移量开始。

如果 mmap() 成功运行,我们会得到 0。 否则,返回 MAP_FAILED。


C语言使用mmap()写入内存

让我们通过练习不同的例子来理解 mmap()。

示例代码(用于内存分配):

#include <stdio.h>
#include <sys/mman.h>

int main(){
    int N=5;
    int *ptr = mmap ( NULL, N*sizeof(int),
                     PROT_READ | PROT_WRITE,
                     MAP_PRIVATE | MAP_ANONYMOUS,
                     0, 0 );

    if(ptr == MAP_FAILED){
        printf("Mapping Failed\n");
        return 1;
    }

    for(int i=0; i<N; i++)
        ptr[i] = i*10;

    for(int i=0; i<N; i++)
        printf("[%d] ",ptr[i]);

    printf("\n");
    int err = munmap(ptr, 10*sizeof(int));
    if(err != 0){
        printf("Unmapping Failed\n");
        return 1;
    }

    return 0;
}

输出:

[0] [10] [20] [30] [40]

我们使用 mmap() 函数来分配内存,在分配时我们使用 PROT_READ | PROT_WRITE 保护来对映射区域进行读写操作。

我们使用 MAP_PRIVATE 标志是因为我们不想与其他进程共享映射区域,而使用 MAP_ANONYMOUS 是因为我们还没有映射文件。

出于同样的原因,文件描述符和偏移量被设置为 0。

示例代码(用于进程间通信):

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

int main(){

    int Number=5;
    int *ptr = mmap(NULL,Number*sizeof(int),
                    PROT_READ | PROT_WRITE,
                    MAP_SHARED | MAP_ANONYMOUS,
                    0,0);

    if(ptr == MAP_FAILED){
        printf("Mapping Failed\n");
        return 1;
    }

    for(int i=0; i < Number; i++){
        ptr[i] = i + 7;
    }

    printf("Initial array's values:");
    for (int i = 0; i < Number; i++ ){
        printf(" %d", ptr[i] );
    }
    printf("\n");
    pid_t child_pid = fork();

    if ( child_pid == 0 ){
        //child
        for (int i = 0; i < Number; i++){
            ptr[i] = ptr[i] * 5;
        }
    }else{
        //parent
        waitpid ( child_pid, NULL, 0);
        printf("\nParent:\n");
        printf("Updated array's values:");
        for (int i = 0; i < Number; i++ ){
           printf(" %d", ptr[i] );
        }
        printf("\n");
    }

    int err = munmap(ptr, Number*sizeof(int));

    if(err != 0){
        printf("Unmapping Failed\n");
        return 1;
    }
    return 0;
}

输出:

Initial array's values: 7 8 9 10 11
Initial array's values: 7 8 9 10 11

Parent:
Updated array's values: 35 40 45 50 55

我们最初用一些值初始化数组。 然后,孩子的过程改变了价值观。

此外,值由父进程读取,子进程更改了这些值,因为映射内存正在与两个(子进程和父进程)共享。 我们还使用 munmap() 来删除内存映射。

转载请发邮件至 1244347461@qq.com 进行申请,经作者同意之后,转载请以链接形式注明出处

本文地址:

相关文章

在 C 语言中使用 typedef enum

发布时间:2023/05/07 浏览次数:181 分类:C语言

本文介绍了如何在 C 语言中使用 typedef enum。使用 enum 在 C 语言中定义命名整数常量 enum 关键字定义了一种叫做枚举的特殊类型。

C 语言中的静态变量

发布时间:2023/05/07 浏览次数:151 分类:C语言

本文介绍了如何在 C 语言中使用静态变量。在 C 语言中使用 static 变量在函数调用之间保存变量值

C 语言中生成随机数

发布时间:2023/05/07 浏览次数:64 分类:C语言

本文演示了如何在 C 语言中生成随机数。使用 rand 和 srand 函数在 C 语言中生成随机数

C 语言中的 i++ 与++i

发布时间:2023/05/07 浏览次数:83 分类:C语言

本文演示了如何在 C 语言中使用前缀增量与后缀增量运算符。C 语言中++i 和 i++ 记号的主要区别

C 语言中获取当前工作目录

发布时间:2023/05/07 浏览次数:182 分类:C语言

本文演示了如何在 C 语言中获取当前工作目录。使用 getcwd 函数获取当前工作目录的方法

C 语言中的位掩码

发布时间:2023/05/07 浏览次数:126 分类:C语言

本文介绍了如何在 C 语言中使用位掩码。使用 struct 关键字在 C 语言中定义位掩码数据

C 语言中的排序函数

发布时间:2023/05/07 浏览次数:181 分类:C语言

本文演示了如何在 C 语言中使用标准库排序函数。使用 qsort 函数对 C 语言中的整数数组进行排序

C 语言中的 extern 关键字

发布时间:2023/05/07 浏览次数:114 分类:C语言

本文介绍了如何在 C 语言中使用 extern 关键字。C 语言中使用 extern 关键字来声明一个在其他文件中定义的变量

C 语言中的 #ifndef

发布时间:2023/05/07 浏览次数:186 分类:C语言

本文介绍了如何在 C 语言中使用 ifndef。在 C 语言中使用 ifndef 保护头文件不被多次包含 C 语言中的头文件用于定义同名源文件中实现的函数的接口。

扫一扫阅读全部技术教程

社交账号
  • https://www.github.com/onmpw
  • qq:1244347461

最新推荐

教程更新

热门标签

扫码一下
查看教程更方便