【问题标题】:C/C++ - Memory map file using mmapC/C++ - 使用 mmap 的内存映射文件
【发布时间】:2023-03-06 07:07:02
【问题描述】:

我是内存映射文件的新手,有点困惑。是否可以映射大于内存总量的文件,因为据我所知,内存映射使用需求分页,并且只会在内存中保存当前相关的页面。当使用的空间超过实际内存时,这是正确的还是我的应用程序会崩溃。

谢谢

编辑 操作系统:Ubuntu 14.04 LTS x86_64 App-Bitness:64bit(我猜:指针是 8 字节)

我正在尝试从映射文件中分配内存,以便将树存储在映射文件中。

#define MEMORY_SIZE 300000000

unsigned char *mem_buffer;
void *start_ptr;

void *my_malloc(int size) {
    unsigned char *ptr = mem_buffer;
    mem_buffer += size;

    return ptr;
}

void *my_calloc(int size, int object_size) {
    unsigned char *ptr = mem_buffer;
    mem_buffer += (size * object_size);

    return ptr;
}

void init(const char *file_path) {
    int fd = open(file_path, O_RDWR, S_IREAD | S_IWRITE);

    if (fd < 0) {
        perror("Could not open file for memory mapping");
        exit(1);
    }

    start_ptr = mmap(NULL, MEMORY_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
    mem_buffer = (unsigned char *) start_ptr;

    if (mem_buffer == MAP_FAILED) {
        perror("Could not memory map file");
        exit(1);
    }

    printf("Successfully mapped file.\n");
}

void unmap() {
    if (munmap(start_ptr, MEMORY_SIZE) < 0) {
        perror("Could not unmap file");
        exit(1);
    }

    printf("Successfully unmapped file.\n");
}

主要方法:

int main(int argc, char **argv) {

    init(argv[1]);

    unsigned char *arr = (unsigned char *) my_malloc(6);
    arr[0] = 'H';
    arr[1] = 'E';
    arr[2] = 'L';
    arr[3] = 'L';
    arr[4] = 'O';
    arr[5] = '\0';

    unsigned char *arr2 = (unsigned char *) my_malloc(5);
    arr2[0] = 'M';
    arr2[1] = 'I';
    arr2[2] = 'A';
    arr2[3] = 'U';
    arr2[4] = '\0';

    printf("Memory mapped string1: %s\n", arr);
    printf("Memory mapped string2: %s\n", arr2);

    struct my_btree_node *root = NULL;

    insert(&root, arr, 10);
    insert(&root, arr2, 20);

    print_tree(root, 0, false);

//  cin.ignore();

    unmap();

    return EXIT_SUCCESS;
}

【问题讨论】:

  • mmap失败后errno的值是多少?
  • @Malkocoglu errno 的值为 12
  • @Malkocoglu 我把问题移到这里http://stackoverflow.com/questions/29213142/c-memory-map-a-b-tree,因为这里提出的问题已经得到解答。

标签: c mmap


【解决方案1】:

映射大于内存总量的文件是可能的(并且非常正常),但您的应用程序必须能够解决它。如果您的系统/应用程序是 32 位,则地址范围有限。您的系统和应用程序必须是 64 位才能处理大于数 GB 大小的文件...

请注意:即使您的文件很小,您仍可能无法对其进行映射。也许您只是将内存分配给其他用途(线程的堆栈空间、应用程序缓冲区/列表的内存等),从而消耗了您的地址空间

【讨论】:

  • 实际上是 4GB,但实际上是 2GB 或 3GB,具体取决于寻址模式。
  • 我必须使用mmap64 才能使用整个64 位还是mmap 足够?
  • @Malkocoglu 现在的问题是如果我尝试映射比可用内存更大的大小,我会收到错误Cannot allocate memory。我是否必须手动取消映射,然后使用另一个偏移量进行映射才能处理大文件?
  • @aQuip:您的系统和应用程序位数是多少?如果是 32 位,这个错误很可能是正常的。告诉我们你的比特并给我们看一些代码!
【解决方案2】:

这是The GNU C Library: Memory-mapped I/O的摘录

由于在物理内存不足时可以将映射的页面存储回它们的文件,因此可以将文件映射到比物理内存和交换空间大几个数量级的数量级。唯一的限制是地址空间。 32 位机器上的理论限制为 4GB - 但是,实际限制会更小,因为某些区域将被保留用于其他目的。

【讨论】:

    猜你喜欢
    • 2013-02-17
    • 2016-12-08
    • 2020-11-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多