3

我对内存映射非常陌生,并试图了解内存映射文件以在我的项目(基于 Linux)中使用它们。我的要求是写入然后从内存映射文件中读取。我写了一个示例程序,它只写并且工作正常,但我有一些非常基本的疑问,因为我不理解这个内存映射的基础。

#include <unordered_map>
#include <boost/iostreams/device/mapped_file.hpp>
using namespace boost::interprocess;
using namespace std;
typedef unordered_map<int, string> work;
int main()
{
        boost::iostreams::mapped_file_params  params;
        params.path = "map.dat";
        params.new_file_size = 100;
        params.mode = (std::ios_base::out | std::ios_base::in);
        boost::iostreams::mapped_file  mf;
        mf.open(params);
        work w1;
        w1[0] = "abcd";
        w1[1] = "bcde";
        w1[2] = "cdef";

        work* w = static_cast<work*>((void*)mf.data());
        *w = w1;
        mf.close();
        return 0;
}

我在这里有几个问题:

  1. 当我这样做时: mf.open(params) ,我看到在磁盘上创建了一个大小为 100 的文件。现在当我写入它时,即 *w = w1,磁盘上文件的内容发生了变化。这是否意味着我根本没有使用 RAM,而是直接写入
    磁盘?

  2. 当我执行 mf.size() 时,它总是给我作为创建实际文件的输入的大小。如何找出我实际写入
    内存映射文件的数据大小?

  3. 此外,如果我给 params.new_file_size = 10GB,该大小的文件会在
    磁盘上创建,但不会占用任何磁盘空间。使用 df cmd 确认。为什么这样?-rwx-----。1 根 10000000000 Apr 29 14:26 map.dat

  4. 我读到关闭文件释放了映射。这是否意味着关闭后我会丢失我写的所有数据?但这不是真的,因为我有工作代码,我关闭然后再次打开文件并正确读取它。

  5. 如何删除使用后创建的内存映射文件?通过使用 rm -rf cmd/linux api?

4

1 回答 1

4
  • 当我这样做时: mf.open(params) ,我看到在磁盘上创建了一个大小为 100 的文件。现在当我写入它时,即 *w = w1,磁盘上文件的内容发生了变化。这是否意味着我根本没有使用 RAM,而是直接写入磁盘?

您正在使用内存映射文件。这意味着两者:您正在写入已映射到您的进程空间的“虚拟内存页面”,但实际上是指磁盘块。增长表明页面在写入时提交。

  • 当我执行 mf.size() 时,它总是给我作为创建实际文件的输入的大小。如何找出我实际写入内存映射文件的数据大小?

你不能。您只能使用类似的工具找到提交的块数stat

  • 此外,如果我给 params.new_file_size = 10GB,该大小的文件会在磁盘上创建,但不会占用任何磁盘空间。使用 df cmd 确认。为什么这样?-rwx-----。1 根 10000000000 Apr 29 14:26 map.dat

它分配得很少。例如fallocate在其他平台上使用或类似。

  • 我读到关闭文件释放了映射。这是否意味着关闭后我会丢失我写的所有数据?但这不是真的,因为我有工作代码,我关闭然后再次打开文件并正确读取它。

不,这意味着映射被释放。也就是说,您的进程空间中的 /virtual memory/ 区域现在可以“自由”用于其他用途。

  • 如何删除使用后创建的内存映射文件?通过使用 rm -rf cmd/linux api?

是的。

于 2014-04-30T09:49:47.100 回答