Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/153.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 用于保存大量数据的带有map_ANON的mmap_C++_Mmap - Fatal编程技术网

C++ 用于保存大量数据的带有map_ANON的mmap

C++ 用于保存大量数据的带有map_ANON的mmap,c++,mmap,C++,Mmap,我正在从事一个项目,该项目需要生成大量数据(即数百GB)并在以后进行处理。目前,我正在使用C++,我想使用MMAP*()来创建一些虚拟内存来保存数据。显而易见的方法是创建一个文件并使用mmap()将100GB映射到该文件,然后我们应该能够从映射的内存中读取/写入数据。大概是这样的: int file = open("disk_cache", O_RDWR|O_CREAT, 0644); lseek (file,//100GB, SEEK_SET); w

我正在从事一个项目,该项目需要生成大量数据(即数百GB)并在以后进行处理。目前,我正在使用C++,我想使用MMAP*()来创建一些虚拟内存来保存数据。显而易见的方法是创建一个文件并使用mmap()将100GB映射到该文件,然后我们应该能够从映射的内存中读取/写入数据。大概是这样的:

    int file = open("disk_cache", O_RDWR|O_CREAT, 0644);
    lseek (file,//100GB, SEEK_SET);
    write (file, "", 1);

    auto* mapPtr = (unsigned*)mmap(nullptr, //100GB,  PROT_WRITE|PROT_READ, MAP_SHARED, file, 0);
    if ( mapPtr == MAP_FAILED) {
        perror("mmap");
        return ;
    }
    Generate_data(mapPtr); \\ write/generate data here; 
    Process_data(mapPtr);  \\ read/access data here; 
    if (munmap(mapPtr, //100GB) == -1) {
        perror("mmap:");
        return ;
    }
    close(file);
    if( remove("disk_cache") != 0 ){
       perror("remove the file:");
    }
    auto* mapPtr = (unsigned*)mmap(nullptr,  //100GB ,  PROT_WRITE|PROT_READ, MAP_SHARED|MAP_ANON|MAP_NORESERVE, -1, 0);
    if ( mapPtr == MAP_FAILED) {
        perror("mmap");
        return ;
    }
上面的代码工作得很好,但看起来有点多余,我必须创建一个文件,然后删除它。我在考虑是否可以映射ANON标志来映射数据,所以我尝试了以下方法:

    int file = open("disk_cache", O_RDWR|O_CREAT, 0644);
    lseek (file,//100GB, SEEK_SET);
    write (file, "", 1);

    auto* mapPtr = (unsigned*)mmap(nullptr, //100GB,  PROT_WRITE|PROT_READ, MAP_SHARED, file, 0);
    if ( mapPtr == MAP_FAILED) {
        perror("mmap");
        return ;
    }
    Generate_data(mapPtr); \\ write/generate data here; 
    Process_data(mapPtr);  \\ read/access data here; 
    if (munmap(mapPtr, //100GB) == -1) {
        perror("mmap:");
        return ;
    }
    close(file);
    if( remove("disk_cache") != 0 ){
       perror("remove the file:");
    }
    auto* mapPtr = (unsigned*)mmap(nullptr,  //100GB ,  PROT_WRITE|PROT_READ, MAP_SHARED|MAP_ANON|MAP_NORESERVE, -1, 0);
    if ( mapPtr == MAP_FAILED) {
        perror("mmap");
        return ;
    }
它可以正常工作,直到数据超过64 GB(因为我在一台有64 GB内存的服务器上运行它),我的问题如下:

(1) 似乎MAP_ANON将所有数据保存在Mem上,而不是磁盘上?我想知道为什么会这样?有什么办法可以避免吗?我认为MAP_ANON会将所有数据保存在dev/zero中,我们可以从那里安全地存储/访问数据

(2) 此外,我使用多线程(即32核)来生成/访问数据。对于mmap(),随机访问数据非常有效。但将数据存储/写入内存的速度似乎较慢。我做了一些快速的实验,看起来ofstream比mmap()快,尤其是当数据大于Mem时。我觉得我可能对mmap做了些错事()。在使用mmap()编写/存储大于Mem的数据时,我需要注意哪些事项?最好的方法是什么


感谢您的帮助。

您可以删除该文件并继续使用它。然后您有一个“文件”存储,但当它上的最后一个有效fd关闭时,它将释放该存储,因此当您调用close时。您还应该注意多线程环境中的同步。谢谢您的回复。是 啊正如我所说,我们绝对可以做到。我只是想知道MAP_ANON是否仍将所有数据保存在Mem中。如果是这样,为什么我们需要这面旗帜?看起来我们可以使用全局变量或malloc,并将引用/指针传递给子线程。只要我们照顾好每一个线程,它就应该工作。这个标志的存在一定有原因。内存是什么?事实上,数据需要存在于“某处”,因此它在内存中,但最终可以在磁盘上交换。对不起,我的错。至于记忆,我指的是RAM。由于我们的服务器只有64GB的RAM,它无法在RAM中容纳所有数据(即高达数百GB)。这就是为什么我们决定使用mmap()将数据保存在磁盘上,并在需要时读取它。我想MAP_ANON会在磁盘上为我们打开一些内存,这样我们就可以使用它,而不必担心在完成后扩展/删除文件。但显然,我错了,MAP_ANON仍然分配RAM上的所有数据,而不是磁盘上的数据。当数据超过64 GB时,它将被OMM终止。