代码之家  ›  专栏  ›  技术社区  ›  sanjoyd

POSIX系统上保持同步的内存映射文件

  •  1
  • sanjoyd  · 技术社区  · 14 年前

    void continuous_mmap (void)
    {
     struct stat buf;
     int fd = open("file_one", O_RDONLY), i;
     char *contents;
    
     fstat(fd, &buf);
     contents = mmap(NULL, buf.st_size, PROT_WRITE, MAP_PRIVATE, fd, 0);
     close (fd);
     mprotect(contents, buf.st_size, PROT_READ);
     for (i = 0; i < 15; i++) {
      printf ("%s\n", contents);
      sleep (1);
     }
     munmap(contents, buf.st_size);
    }
    

    首先,文件保持同步(外部编辑和保存文件会自动打印更新的内容),即使是附加到文件中。我的代码如何能够访问超出我映射的字节数(初始文件大小)的数据而不进行分段?是因为 mmap POSIX 系统(我在 mmap公司

    其次,文本如何自动附加 '0' ? 是因为未映射的字节会自动归零吗?这种行为可以信赖吗?

    3 回复  |  直到 14 年前
        1
  •  2
  •   Jens Gustedt    14 年前

    系统应始终零填充任何 对象末尾的部分页。 对象的页面超出其 结束。

    • 如果是这样的话,这种行为能被依赖吗 POSIX系统概述(I) 找不到任何此类要求

    您不应该使用 mmap 要求这个但是 ftruncate 把你的文件加长到你的需要。

        2
  •  1
  •   R.. GitHub STOP HELPING ICE    14 年前

    POSIX甚至不要求非平凡的页面大小;理论上,一个实现的“页面”大小可以是1字节。类似地,似乎没有指定从超过文件大小的页面的剩余部分读取零。我可以想象一些被破坏的实现会泄漏这里被截断的旧文件内容,但是我会认为一个重大的安全/隐私漏洞会使这样的实现在现实世界中变得无关紧要。他们当然可以用 0xDEADBEEF 那你就不走运了。

    即使您可以假设为零填充(这可能是大多数现实世界操作系统的情况),我也会提醒您不要使用它。如果文件恰好是系统页面大小的倍数,会发生什么情况?突然你的代码读到结尾时崩溃了,或者(可能更糟)读到了一个不相关的页面,而这个页面恰好被映射到了你文件的映射附近。这是一个非常严重的bug,您可能无法捕捉到,因为拥有一个系统页面大小的精确倍数的文本文件的概率非常低。

        3
  •  0
  •   caf    14 年前

    MAP_PRIVATE ,是因为您尚未写入映射,所以系统尚未向您提供文件页的私有副本。这种行为是允许的,但不是必须的。

    contents[0] 在循环之前,它会 查看外部更改。