查看原文
其他

Rust 生态蜜蜂|安全抽象启示录:mmap 内存映射

张汉东 觉学社 2022-08-29
前言
因觉学,求绝学。Rust 生态蜜蜂,是觉学社公众号开启的一个付费专栏。生态蜜蜂,顾名思义,是从 Rust 生态的中,汲取养分,供我们成长。计划从2022年7月第二周开始,到2022年12月最后一周结束。预计至少二十篇周刊,外加一篇Rust年度报告总结抢读版。本专栏可以在公众号菜单「生态蜜蜂」中直接进入。海外用户可以去 https://rustbee.zhubai.love/ 订阅。

目录

  • Mmap 基础概念简介
  • Rust 如何对 mmap 进行安全抽象
    • mmap 的安全问题
    • Rust 安全抽象迎来的挑战
    • 相似的 /proc/self/mem 问题
    • 目前生态中mmap相关库的解决方案
  • mmap 在 Rust 生态中的应用
  • 小结

Mmap 基础概念简介

mmap 即 memory map,它是Linux 内提供的一种内存映射文件的方法,即将一个文件或者其它对象映射到进程的用户空间,实现文件磁盘地址和进程虚拟地址空间中一段虚拟地址的一一对映关系。之后,进程就可以采用指针的方式读写操作这一段内存,而系统会自动回写脏页面到对应的文件磁盘上,即完成了对文件的操作而不必再调用read/write等系统调用函数。

程序执行写操作直接将数据写到缓存中,然后将页高速缓存中被写入的页面标记为“脏”,并且将这些“脏”页面加入到脏链表中。最后,回写进程会将脏链表中的脏页刷新到磁盘中,最终做到保证磁盘和内存中数据的一致性。

这种方式和通常的读取文件的方式相比,效率更高。因为 read 系统调用首先会把文件内容从硬盘拷贝到内核空间的一个缓冲区,然后再将这些数据拷贝到用户空间,一共经历4次用户态和内核态的上下文切换4次拷贝(两次cpu拷贝和两次 DMA 拷贝)。而 mmap 通过 mmap() 系统调用,直接将文件映射到用户空间,然后根据缺页中断在需要的时候利用 DMA 技术将数据直接从硬盘拷贝到用户空间,完全没有 CPU 拷贝。所以 mmap 的效率更高。

通过 mmap 机制,磁盘上的文件就如直接在内存中一样,开发者可以把访问磁盘文件简化为按地址访问内存,这样一来,应用程序自然不需要使用文件系统的 write(写入)、read(读取)、fsync(同步)等系统调用,只要面向内存的虚拟空间进行开发即可,可以简化编程。

mmap 主要用途有两个:

  • 大数据量文件的读取,有效的提高磁盘和内存间数据通信的性能
  • 进程间快速的共享内存,实现进程间高效的通信

但是 mmap 也有很大的缺陷:

  • mmap 使用时必须实现指定好内存映射的大小,并不适合变长文件
  • 如果更新文件的操作很多,mmap 避免两次拷贝的优势就会被抵消,其效率不一定比 read/write系统调用更快。所以一般mmap 适合大内存读取。
  • 读写小文件 mmap 效率不高
  • mmap 受限于操作系统内存大小

Rust 如何对 mmap 安全抽象

mmap 的安全问题

想编写正确的 mmap 代码是比较困难的,一般来说需要注意以下两个问题:

购买合集后可阅读剩余82%
#Rust生态蜜蜂
  • 1. Rust 生态蜜蜂|2022-7-24
  • 2. Rust 生态蜜蜂|2022-7-31
  • 3. Rust 生态蜜蜂|2022-08-01
购买合集后可阅读剩余82%

#Rust生态蜜蜂

微信扫一扫付费阅读本文

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存