`shm_open`使用哪种类型的内存对象?

4
通常情况下,共享内存是通过映射到进程地址空间的磁盘文件部分来实现的。每当在共享区域发生内存访问时,文件系统都会涉及写入磁盘上的更改,这是一个很大的开销。

通常,对fopen()的调用返回一个文件描述符,该文件描述符被传递给mmap()以创建文件的内存映射。显然,shm_open的工作方式也相同。它返回一个文件描述符,甚至可以与普通文件操作(如ftruncateftellfseek等)一起使用。我们将字符串指定为shm_open的参数,但与fopen()不同,它不是可见文件系统(挂载的硬盘驱动器、闪存驱动器、固态硬盘等)上的真实文件的名称。完全不相关的进程可以使用相同的字符串名称将同一区域映射到其地址空间中。

那么,传递给shm_open的字符串参数是什么?shm_open创建/打开了什么?它是一种在某些临时文件系统(例如/tmp)上的文件,最终由许多进程用于创建共享区域(我认为它必须是某种文件,因为它返回文件描述符)?还是一种由内核支持的神秘和隐藏的文件系统?

人们说shm_openfopen快,因为没有涉及磁盘操作,所以我提出的理论是,内核使用一个不可见的基于RAM的文件系统来实现带有shm_open的共享内存!

1
你为什么认为共享内存被映射到磁盘上? - Ed Heal
1
相关链接:https://superuser.com/questions/45342/when-should-i-use-dev-shm-and-when-should-i-use-tmp,https://dev59.com/_Wkw5IYBdhLWcg3wp8Kc - Ilja Everilä
1
{btsdaf} - Karim Manaouil
1
请问您能否给我一个参考? - Ed Heal
2
不,磁盘并不相关。您可以使用shm_open而无需任何交换空间。请参阅shm_overview(7),而/dev/shm/通常是一个挂载的tmpfs文件系统,因此不要使用任何磁盘。 - Basile Starynkevitch
显示剩余7条评论
2个回答

7
通常情况下,共享内存是使用映射到进程地址空间的磁盘文件部分实现的。但至少在运行最新版本Linux发行版且有足够内存(例如至少8G字节)的桌面或笔记本电脑上,这种说法通常是错误的。所以,磁盘不相关。你可以使用shm_open而不需要任何交换空间。请参阅shm_overview(7),并注意/dev/shm/通常是一个tmpfs挂载的文件系统,因此不要使用任何磁盘。请参阅tmpfs(5)。并且tmpfs不使用磁盘(除非达到thrashing状态,这是不太可能的),因为它在虚拟内存中工作。
这通常是错误的。在大多数系统中,最近写入的文件在分页缓存中,不会很快写入磁盘(顺便说一下,这就是为什么关机过程需要调用sync(2),否则很少使用...)。
顺便说一句,在大多数桌面和笔记本电脑上很容易观察到。硬盘有一些LED灯,当使用shm_open和相关调用时,你看不到它闪烁。此外,你还可以使用proc(5)(特别是/proc/diskstats等...)查询内核的磁盘活动。

现在有意义了。所以传递给 shm_open 的参数是 /dev/shm/ tempfs 文件系统上的文件名? - Karim Manaouil
1
是的,这在shm_overview(7)中有记录。在向SO或其他地方提问之前,您应该阅读文档和man页面。 - Basile Starynkevitch

5
通常,共享内存是使用映射到进程地址空间的磁盘文件部分实现的。每当在共享区域上发生内存访问时,文件系统都会涉及写入磁盘上的更改,这是一个巨大的开销。
看起来有些傲慢,也不完全正确。实现IPC(进程间通信)中的共享内存区域的几乎所有机器都具有虚拟内存单元来支持该功能。可能没有任何特定共享内存段或其任何一部分的持久存储支持。只有被分页出去的部分(如果有)需要由这样的存储支持。
似乎shm_open也是这样工作的。它返回一个文件描述符,甚至可以与常规文件操作(如ftruncateftellfseek等)一起使用。 shm_open()的接口模仿了open(),并返回一个文件描述符,可以与某些通用I/O函数有意义地一起使用,但这并不意味着shm_open()在任何更广泛的意义上“以相同的方式工作”。几乎所有系统资源都表示为进程文件。这提供了一个更简单的整体系统界面,但并不意味着底层资源的任何共性,除了它们可以通过相同的函数进行操作-在确实如此的情况下。
那么,传递给shm_open的字符串参数是什么,shm_open创建/打开了什么?
该参数是标识共享内存段的字符串。您已经知道了这一点,但似乎认为其中还有更多内容。至少在(POSIX)规定shm_open接口的级别上,没有更多内容。该标识符主要对内核有意义。不同的实现以不同的方式处理细节。
它可能是一些临时文件系统(/tmp)上的文件,最终由许多进程使用来创建共享区域,但可能不是。为其提供的任何文件系统界面很可能是虚拟文件系统,而不是磁盘上实际可访问的文件。如果使用持久存储,则可能是从系统交换空间中提供的。
这样的结论是不合理的。套接字和管道也通过文件描述符表示,但它们没有相应的可访问文件。
还是一种神秘而隐藏的由内核支持的文件系统?

那可能是一个更好的概念,但是可能没有任何持久存储。然而,只要存在一些存储空间,它很可能是系统交换空间的一部分,这并不是什么神秘的东西。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接