为了账号安全,请及时绑定邮箱和手机立即绑定

我什么时候应该使用mmap进行文件访问?

我什么时候应该使用mmap进行文件访问?

C
喵喵时光机 2019-07-23 15:53:54
我什么时候应该使用mmap进行文件访问?POSIX环境提供至少两种访问文件的方法。有标准的系统调用open(),read(),write(),和朋友,但也有使用的选项mmap(),将文件映射到虚拟内存。何时优先使用一个而不是另一个?它们各自的优势是什么,包括两个接口?
查看完整描述

3 回答

?
阿晨1998

TA贡献2037条经验 获得超6个赞

如果你有多个进程从同一个文件以只读方式访问数据,那么mmap很棒,这在我编写的服务器系统类型中很常见。mmap允许所有这些进程共享相同的物理内存页面,从而节省大量内存。

mmap还允许操作系统优化分页操作。例如,考虑两个程序; 程序A将1MB文件读入使用malloc创建的缓冲区,程序B将1MB文件格式化为内存。如果操作系统必须将A的一部分内存交换掉,它必须将缓冲区的内容写入交换,然后才能重用内存。在B的情况下,任何未修改的mmap页面都可以立即重用,因为操作系统知道如何从他们mmap的现有文件中恢复它们。(操作系统可以通过最初将可写mmap的页面标记为只读并捕获seg错误来检测哪些页面未修改,类似于写入时复制策略)。

mmap对于进程间通信也很有用。您可以在需要通信的进程中将文件映射为读/写,然后在mmap'd区域中使用同步原语(这是MAP_HASSEMAPHORE标志的用途)。

如果您需要在32位计算机上使用非常大的文件,那么mmap的一个地方可能很尴尬。这是因为mmap必须在进程的地址空间中找到一个连续的地址块,该地址空间足够大,以适应所映射文件的整个范围。如果您的地址空间变得碎片化,这可能会成为一个问题,您可能有2 GB的地址空间可用,但没有单独的范围可以适合1 GB的文件映射。在这种情况下,您可能必须将文件映射到比您想要的更小的块中。

mmap作为读/写替代品的另一个潜在尴尬是你必须在页面大小的偏移量上开始映射。如果您只想在偏移X处获取一些数据,则需要修复该偏移量,以便与mmap兼容。

最后,读/写只是你的方式可以与某些类型的文件的工作。mmap不能用于管道和ttys之类的东西。


查看完整回答
反对 回复 2019-07-23
?
RISEBY

TA贡献1856条经验 获得超5个赞

我发现mmap()不具有优势的一个领域是读取小文件(16K以下)。与仅执行单个read()系统调用相比,读取整个文件的页面错误开销非常高。这是因为内核有时可以在您的时间片中完全满足读取,这意味着您的代码不会被切换掉。由于页面错误,似乎更有可能安排另一个程序,使文件操作具有更高的延迟。


查看完整回答
反对 回复 2019-07-23
?
慕容3067478

TA贡献1773条经验 获得超3个赞

mmap当您对大文件进行随机访问时具有优势。另一个优点是您可以通过内存操作(memcpy,指针算术)访问它,而无需担心缓冲。当结构大于缓冲区时,使用缓冲区时,正常I / O有时会非常困难。处理它的代码通常很难正确,mmap通常更容易。这就是说,工作时有一些陷阱mmap。正如人们已经提到的那样,mmap设置成本非常高,因此仅适用于给定尺寸(从机器到机器)不同。

对于对文件的纯顺序访问,它也不总是更好的解决方案,尽管适当的调用madvise可以缓解问题。

您必须小心架构的对齐限制(SPARC,itanium),使用读/写IO缓冲区通常是正确对齐的,并且在取消引用转换指针时不会陷阱。

您还必须小心,不要在地图外访问。如果在地图上使用字符串函数,并且文件末尾不包含\ 0,则很容易发生。当文件大小不是页面大小的倍数时,它将在大多数情况下工作,因为最后一页填充为0(映射区域的大小始终为页面大小的倍数)。


查看完整回答
反对 回复 2019-07-23
  • 3 回答
  • 0 关注
  • 725 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信