Linux作为一款自由开源的操作系统,其性能和稳定性备受赞誉,被广泛应用于服务器、嵌入式系统等领域。其中,mmap()系统调用是Linux有名的一大特色,它允许用户进程通过建立虚拟内存映射来访问文件或设备,实现了一个衔接内存的方法,将磁盘上的文件映射到进程地址空间,提高了文件的访问效率。而mmap64的出现,更是解决了32位平台无法支持大内存访问的问题。本文将。
创新互联公司专业为企业提供东兴网站建设、东兴做网站、东兴网站设计、东兴网站制作等企业网站建设、网页设计与制作、东兴企业网站模板建站服务,十年东兴做网站经验,不只是建网站,更提供有价值的思路和整体网络服务。
一、linux mmap64的概念和原理
1.1 概念
mmap64是由32位机器到64位机器转换时,操作系统为保持兼容,新增的一个系统调用。与mmap()函数相比,主要区别在于支持对大内存的访问。mmap()函数在32位机器上只能映射2GB左右大小的内存,而mmap64则能够在64位机器上支持对更大內存的访问。因此,它在处理大型文件时非常有用。
1.2 原理
mmap64调用原理跟mmap调用基本一样,但其在创建映射时会将offset参数左移32位,以支持64位地址指针。
mmap64的调用格式为:
“`
void *mmap64(void *addr, size_t length, int prot, int flags, int fd, off64_t offset);
“`
其中,
– addr:映射区的开始地址
– length:映射区的长度
– prot:映射区域的保护方式
– flags:映射区域的类型和其他属性
– fd:打开文件的文件描述符 fd。
– offset:被映射内存的起始偏移量,单位为字节。
二、Linux mmap64的应用
2.1 mmap64用于内存映射文件
mmap64支持通过共享内存与IPC通信,但更常见的应用是内存映射文件。mmap64可以将一个文件(或设备)映射到用户空间的一段内存中,所有对这片内存的读写操作都将直接对文件进行,而不需要使用read()/write()等系统调用。
2.2 mmap64用于大文件读写操作
mmap64还可以用于大文件的读写操作。相比一次读取大文件到内存中,使用mmap64将文件映射到内存中,可以避免内存不足的情况发生。同时,尤其适用于通过多进程方式访问同一个文件的情景。由于多进程共享一个文件映射,不需要复制整个文件,而是共享同一个内存区域,避免了复制的时间和性能开销。这种方法在多进程之间较为常见。
2.3 mmap64用于动态内存管理
mmap64还可以用在动态内存管理中。mmap64系统调用也可以用于确定内存的起始地址。mmap64返回的地址使用后可以通过munmap移除,从而使做大过程变得更加灵活。此外,虽然mmap()无法动态地调整映射的长度,但通过使用mremap(),我们可以以原址为中心,调整区域大小。
三、Linux mmap64实际使用中需要注意的事项
3.1 地址保护权限
mmap64将文件映射到内存中,需设置访问该内存的权限,如果内存可写,那么文件也可写;如果是只读的,文件只能读取。
3.2 对文件的访问方式
mmap64常常被用于大型磁盘文件的高效读写。然而,需要注意的是,使用mmap时,对于频繁更改的文件,如日志文件、数据库文件等,如果不适当地使用mmap,将会对磁盘空间产生很大的压力。所以,对于频繁修改文件的应用,应尽量避免使用mmap。
3.3 应防止野指针
使用mmap64函数映射一个文件时,注意内存块是否要求清空,否则可能会引发安全性问题。这时需要注意让系统保证这段内存避免产生野指针。
四、Linux mmap64
可以出,Linux mmap64作为一项重要的内存映射技术,是在Linux系统下开发软件的不可或缺的一项技能。mmap64可以用于内存和磁盘之间进行高效率的交换数据;通过mmap64可以更好的集成磁盘访问和内存访问;在操作大文件时提供了更好的支持等等。Linux mmap64不仅可以用于文件的内存映射,还能够通过设置内存的保护以实现内存管理,对多进程共享内存等使用都非常方便。合理地使用mmap64将显著改善软件的计算性能。在Linux平台下,若能熟练地掌握mmap64的使用方法,并且结合各类应用场景,将会使代码的效率更加卓越。
成都网站建设公司-创新互联为您提供网站建设、网站制作、网页设计及定制高端网站建设服务!
关于 Linux 共享内存,写得更好的应该是宋宝华的 《世上更好的共享内存》 一文。
本文可以说是对这篇文章的学习笔记,顺手练习了一下 rust libc —— shichaoyuan/learn_rust/linux-shmipc-demo
按照宋宝华的总结,当前有四种主流的共享内存方式:
前两种方式比较符合传统的用法,共享内侍碧存做为进程间通信的媒介。
第三种方式更像是通过传递内存“句柄”进行数据传输。
第四种方式是为设备间传递数据设计,避免内存拷贝,直接传递内存“句柄”。
这里尝试了一下第二种和第三种方式。
这套 API 应该是最档缺普遍的 —— shm_open + mmap,本质上来说 Aeron 也是用的这种方式(关于 Aeron 可以参考 我之前的文章 )。
看一下 glibc 中 shm_open 函数的实现就一清二楚了:
shm_open 函数就是在 /dev/shm 目录下建文件,该目录挂载为 tmpfs,至于 tmpfs 可以简单理解为存储介质是内存的一种文件系统,更准确的理解可以参考官方文档 tmpfs.txt 。
然后通过 mmap 函数将 tmpfs 文件映射到用户空间就可以随意操作了。
优点:
这种方式更大的优势在于共享的内存是有“实体”(也就是 tmpfs 中的文件)的,所以多个进程可以很容易通过文件名这个信息构建共享内存结构,特别适合把共享内存做为通信媒介的场景(例如 Aeron )。
缺点:
如果非要找一个缺点的话,可能是,文件本身独立于进程的生命周期,在使用完毕后需要注意删除文件(仅仅行谈辩 close 是不行的),否则会一直占用内存资源。
memfd_create 函数的作用是创建一个匿名的文件,返回对应的 fd,这个文件当然不普通,它存活在内存中。更准确的理解可以参考官方文档 memfd_create(2) 。
直观理解,memfd_create 与 shm_open 的作用是一样的,都是创建共享内存实体,只是 memfd_create 创建的实体是匿名的,这就带了一个问题:如何让其它进程获取到匿名的实体?shm_open 方式有具体的文件名,所以可以通过打开文件的方式获取,那么对于匿名的文件怎么处理呢?
答案是:通过 Unix Domain Socket 传递 fd。
rust 的 UDS 实现:
rust 在 std 中已经提供了 UDS 的实现,但是关于传递 fd 的 send_vectored_with_ancillary 函数还属于 nightly-only experimental API 阶段。所以这里使用了一个三方 crate —— sendfd ,坦白说可以自己实现一下,使用 libc 构建好 SCM_RIGHTS 数据,sendmsg 出去即可,不过细节还是挺多,我这里就放弃了。
这套 API 设计更灵活,直接拓展了我的思路,本来还是受限于 Aeron 的用法,如果在这套 API 的加持下,是否可以通过传递数据包内存块(fd)真正实现零拷贝呢?
优点:
灵活。
缺点:
无
linux mmap64的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于linux mmap64,深入探究Linux mmap64的实现及应用,探讨一下 Linux 共享内存的 N 种方式的信息别忘了在本站进行查找喔。
香港云服务器机房,创新互联(www.cdcxhl.com)专业云服务器厂商,回大陆优化带宽,安全/稳定/低延迟.创新互联助力企业出海业务,提供一站式解决方案。香港服务器-免备案低延迟-双向CN2+BGP极速互访!
网站名称:深入探究Linuxmmap64的实现及应用(linuxmmap64)
浏览路径:http://www.csdahua.cn/qtweb/news38/551138.html
网站建设、网络推广公司-快上网,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等
声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 快上网