英文:
Why does the memory mapped file ever need to be flushed when access is RDWR?
问题
我正在阅读golang的一个内存映射文件实现,https://github.com/edsrzf/mmap-go/。首先,他描述了几种访问模式:
// RDONLY 将内存映射为只读模式。
// 尝试对MMap对象进行写操作将导致未定义的行为。
RDONLY = 0
// RDWR 将内存映射为读写模式。对MMap对象的写操作将更新底层文件。
RDWR = 1 << iota
// COPY 将内存映射为写时复制模式。对MMap对象的写操作将影响内存,但底层文件将保持不变。
COPY
但在gommap的测试文件中,我看到了这样的代码:
func TestReadWrite(t *testing.T) {
mmap, err := Map(f, RDWR, 0)
... 省略部分代码...
mmap[9] = 'X'
mmap.Flush()
那么,如果访问模式是RDWR,为什么他需要调用Flush来确保内容被写入文件呢?
或者是操作系统在管理这个过程,只有在认为需要写入时才会进行写入?
如果是最后一种情况,请您能否详细解释一下——我所了解的是,当操作系统内存不足时,它会将内容写入文件并释放内存。这样理解对吗?这个过程只适用于RDWR还是只适用于COPY?
谢谢。
英文:
I was reading through one of golang's implementation of memory mapped files, https://github.com/edsrzf/mmap-go/. First he describes the several access modes:
// 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
But in gommap test file I see this:
func TestReadWrite(t *testing.T) {
mmap, err := Map(f, RDWR, 0)
... omitted for brevity...
mmap[9] = 'X'
mmap.Flush()
So why does he need to call Flush to make sure the contents are written to the file if the access mode is RDWR?
Or is the OS managing this so it only writes when it thinks it should?
If the last option, could you please explain it in a little more detail - what i read is that when the OS is low in memory it writes to the file and frees up memory. Is this correct and does it apply only to RDWR or only to COPY?
Thanks
答案1
得分: 13
该程序使用mmap
函数映射内存区域。然后,它修改了映射的区域。系统不需要立即将这些修改写回到底层文件中,因此对该文件的read
调用(在ioutil.ReadAll
中)可能返回文件之前的内容。
系统会在你进行修改后的某个时间点将更改写入文件中。
系统允许在进行修改后的任何时间将更改写入文件中,但默认情况下不保证何时写入这些更改。你只知道(除非系统崩溃),这些更改将在将来的某个时间点被写入。
如果你需要确保更改已在某个时间点写入文件中,那么你必须调用msync
函数。
mmap.Flush
函数使用MS_SYNC
标志调用msync
。当该系统调用返回时,系统已将修改写入底层文件,因此任何后续的read
调用都将读取修改后的文件。
COPY
选项将映射设置为MAP_PRIVATE
,因此即使使用msync
(通过Flush
函数),你的更改也永远不会被写回到文件中。
请阅读有关mmap
和msync
的POSIX文档以获取完整的详细信息。
英文:
The program maps a region of memory using mmap
. It then modifies the mapped region. The system isn't required to write those modifications back to the underlying file immediately, so a read
call on that file (in ioutil.ReadAll
) could return the prior contents of the file.
The system will write the changes to the file at some point after you make the changes.
It is allowed to write the changes to the file any time after the changes are made, but by default makes no guarantees about when it writes those changes. All you know is that (unless the system crashes), the changes will be written at some point in the future.
If you need to guarantee that the changes have been written to the file at some point in time, then you must call msync
.
The mmap.Flush
function calls msync
with the MS_SYNC
flag. When that system call returns, the system has written the modifications to the underlying file, so that any subsequent call to read
will read the modified file.
The COPY
option sets the mapping to MAP_PRIVATE
, so your changes will never be written back to the file, even if you using msync
(via the Flush
function).
Read the POSIX documentation about mmap
and msync
for full details.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论