Windows 上的写时复制文件映射 [英] Copy-on-write file mapping on windows
问题描述
我有 3 个进程通过命名管道进行通信:服务器、写入器、读取器.基本思想是 writer 可以在 server 上存储巨大的 (~GB) 二进制 blob,并且 reader(s) 可以检索它.但不是在命名管道上发送数据,而是使用内存映射.
I have 3 processes communicating over named pipes: server, writer, reader. The basic idea is that the writer can store huge (~GB) binary blobs on the server, and the reader(s) can retrieve it. But instead of sending data on the named pipe, memory mapping is used.
服务器使用CreateFileMapping
和PAGE_READWRITE
保护创建一个未命名的文件支持映射,然后将句柄复制到writer.writer 完成其工作后,句柄被复制到任意数量的感兴趣的读者.
The server creates an unnamed file-backed mapping with CreateFileMapping
with PAGE_READWRITE
protection, then duplicates the handle into the writer. After the writer has done its job, the handle is duplicated into any number of interested readers.
writer 在 FILE_MAP_WRITE
模式下用 MapViewOfFile
映射句柄.
The writer maps the handle with MapViewOfFile
in FILE_MAP_WRITE
mode.
reader 在 FILE_MAP_READ|FILE_MAP_COPY
模式下用 MapViewOfFile
映射句柄.
The reader maps the handle with MapViewOfFile
in FILE_MAP_READ|FILE_MAP_COPY
mode.
在阅读器上我想要写时复制语义,所以只要映射是只读的,它就会在所有阅读器实例之间共享.但是,如果读者想要写入其中(例如,就地解析或图像处理),则影响应仅限于使用尽可能少的复制页面的修改过程.
On the reader I want copy-on-write semantics, so as long the mapping is only read it is shared between all reader instances. But if a reader wants to write into it (eg. in-place parsing or image processing), the impacts should be limited to the modifying process with the least number of copied pages possible.
问题
当 reader 尝试写入映射时,它会因分段错误而死亡,就好像没有考虑 FILE_MAP_COPY
一样.上述方法有什么问题?根据 MSDN 这应该可以工作...
The problem
When the reader tries to write into the mapping it dies with segmentation fault as if FILE_MAP_COPY
was not considered.
What's wrong with the above described method? According to MSDN this should work...
我们也在 linux 上实现了相同的机制(使用 mmap
和 fd 传入 AF_UNIX 辅助缓冲区)并且它按预期工作.
We have the same mechanism implemented on linux as well (with mmap
and fd passing in AF_UNIX ancillary buffers) and it works as expected.
推荐答案
MapViewOfFile
设计或/和记录不当.这是ZwMapViewOfSection
. 的 dwDesiredAccess 参数MapViewOfFile
转换为 ZwMapViewOfSection
.
problem here that MapViewOfFile
bad designed or/and documented. this is shell (with restricted functionality) over ZwMapViewOfSection
. the dwDesiredAccess parameter of MapViewOfFile
converted to Win32Protect parameter of ZwMapViewOfSection
.
FILE_MAP_READ|FILE_MAP_COPY
组合转换为 PAGE_READONLY
页面保护,因为这样你会在写入时出现页面错误.
the FILE_MAP_READ|FILE_MAP_COPY
combination converted to PAGE_READONLY
page protection, because this you and get page fault on write.
您只需要使用 FILE_MAP_COPY
标志 - 它转换为 PAGE_WRITECOPY
页面保护,在这种情况下,一切都将起作用.
you need use FILE_MAP_COPY
only flag - it converted to PAGE_WRITECOPY
page protection and in this case all will be work.
最好的解决方案当然是直接使用ZwMapViewOfSection
带有 PAGE_WRITECOPY
页面保护
the best solution of course direct use ZwMapViewOfSection
with PAGE_WRITECOPY
page protection
这篇关于Windows 上的写时复制文件映射的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!