go - 为什么访问是 RDWR 时内存映射文件需要刷新?

标签 go mmap memory-mapped-files

我正在阅读 golang 的内存映射文件实现之一,https://github.com/edsrzf/mmap-go/ .他首先介绍了几种访问方式:

// RDONLY maps the memory read-only.
// Attempts to write to the MMap object will result in undefined behavior.
RDONLY = 0
// RDWR maps the memory as read-write. Writes to the MMap object will update the
// underlying file.
RDWR = 1 << iota
// COPY maps the memory as copy-on-write. Writes to the MMap object will affect
// memory, but the underlying file will remain unchanged.
COPY

但是在 gommap 测试文件中我看到了这个:

func TestReadWrite(t *testing.T) {
  mmap, err := Map(f, RDWR, 0)
  ... omitted for brevity...
  mmap[9] = 'X'
  mmap.Flush()

那么如果访问模式是RDWR,为什么他需要调用Flush来确保内容被写入文件呢?

或者是操作系统在管理这个,所以它只在它认为应该写的时候写?

如果是最后一个选项,您能否更详细地解释一下 - 我读到的是,当操作系统内存不足时,它会写入文件并释放内存。这是正确的吗?它仅适用于 RDWR 还是仅适用于 COPY?

谢谢

最佳答案

程序使用 mmap 映射内存区域。然后它修改映射区域。系统不需要立即将这些修改写回基础文件,因此对该文件的 read 调用(在 ioutil.ReadAll 中)可以返回之前的内容文件。

系统在您做出更改后的某个时候将更改写入文件。 允许在进行更改后随时将更改写入文件,但默认情况下不保证何时写入这些更改。您所知道的是(除非系统崩溃),更改将在将来的某个时间写入。

如果您需要保证更改已在某个时间点写入文件,那么您必须调用msync

mmap.Flush 函数调用带有 MS_SYNC 标志的 msync。当该系统调用返回时,系统已将修改写入底层文件,因此对 read 的任何后续调用都将读取修改后的文件。

COPY 选项将映射设置为 MAP_PRIVATE,因此即使您使用 msync(通过 Flush 函数)。

阅读关于 mmap 的 POSIX 文档和 msync了解全部详情。

关于go - 为什么访问是 RDWR 时内存映射文件需要刷新?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20056099/

相关文章:

c - 能够访问内存位置的 mmap 系统调用操作

java - C++中的内存映射文件用Java读取

windows - 内存映射文件保留在物理内存中?

c# - 将流上的编码更改为 UTF-8 (MemoryMappedViewStream)

image - 在 Golang 中比较 base64 图像字符串

go - 执行系统命令的最佳方式是什么

windows - 解析记录上次运行的日志文件

go - fmt.Scanf 在 Go 中无法正常工作

c - mmap 问题 -> 段错误

c - 捕获对地址范围的所有访问 (Linux)