如何理解内存映射文件?

2017-09-11 15:54:41 +08:00
 kaiser1992
有以下几个问题:
1、什么是内存映射文件?
2、使用内存映射文件的好处是什么?
3595 次点击
所在节点    程序员
16 条回复
cc930415
2017-09-11 15:59:45 +08:00
xenme
2017-09-11 18:24:36 +08:00
直接读写就是需要经过中转。内存映射文件就是跳过了内核,不需要再次复制
misaka20038numbe
2017-09-11 18:37:42 +08:00
就像你家的院子,只要知道地址,谁都可以来。
kaiser1992
2017-09-11 18:44:45 +08:00
@xenme windows 中直接读写 IO 也需要复制?
kaiser1992
2017-09-11 18:50:20 +08:00
@misaka20038numbe 这是进程之间实现通信的一种方式
firemiles
2017-09-11 19:07:04 +08:00
@kaiser1992 内核态数据传到用户态都需要复制吧,除非映射
kaiser1992
2017-09-11 20:18:09 +08:00
@firemiles windows 中也需要?
stephen9357
2017-09-11 21:43:17 +08:00
不需要,只要把同样物理地址再映射一份到用户态地址空间就可以了。参考 DO_DIRECT_IO 和 MDL。
kaiser1992
2017-09-11 22:25:36 +08:00
@stephen9357 windows 中的普通 IO 有从内核空间到用户空间复制数据这个过程吗?
xenme
2017-09-11 22:44:13 +08:00
@kaiser1992 一般 io 都是有的
ryd994
2017-09-12 08:40:08 +08:00
mmap 的基础是 virtual memory (不是 windows 的虚拟内存)
当访问的虚拟地址不在内存里的时候,会 page fault 给内核,内核如果发现这是个 mmap,就会从硬盘读取数据到某段内存,然后把相应的内存页映射到这个虚拟地址

至于 io 过程中的复制,主要是说 read 和 write 这两个
我们看 POSIX read: ssize_t read(int fildes, void *buf, size_t nbyte);
这里 buffer 就是用户空间内存
而 io 读取是先读到内核空间的缓存里,再从缓存复制到 buf,这就是一次内存拷贝
写也是同理

@xenme 跳过内核?喵喵喵?内核还负责翻译虚拟地址呢,你这么厉害能跳过内核了?只有 DOS 才能这么玩
stephen9357
2017-09-12 11:50:05 +08:00
@kaiser1992 你说的普通 IO 是指什么?
使用 Buffered IO 还是 Direct IO,甚至两者都不用都可以,取决于处理该 IO 的设备,可以下载 osr 的 devicetree 查看具体某个设备对象的 flags。
可以参考 ReactOS 的 IO 管理器代码 https://github.com/reactos/reactos/blob/31b47ad45e6384dd538ebfee33c4829945cf2eee/reactos/ntoskrnl/io/iomgr/iofunc.c#L2695
kaiser1992
2017-09-12 12:39:41 +08:00
@stephen9357 谢谢,directIO 的原理是不需要通过内核空间?
kaiser1992
2017-09-12 12:41:28 +08:00
@stephen9357 也就是说 DirectIO 是内存映射的一种实现?
stephen9357
2017-09-12 21:19:54 +08:00
@kaiser1992 DO_DIRECT_IO 也需要内核地址空间。如果使用 DO_BUFFERED_IO,内核会新分配一个 buffer,对内容进行读写操作,最终将该 buffer 拷贝到用户态,而 DO_DIRECT_IO 则不需要拷贝,只是把应用层传递的 buffer 在内核重新映射一次,这样两块地址空间都对应同一块物理内存,就不需要拷贝了,改了这里就是改了那里。
kaiser1992
2017-09-12 21:42:56 +08:00
@stephen9357 谢谢

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/389768

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX