Linux 共享内存: shmget() vs mmap() ?

这个线程中,建议 OP 使用 mmap()而不是 shmget()来获取 Linux 中的共享内存。 我访问了 这个页面和 这个页面以获得一些文档,但是第二个页面给出了一个关于 mmap()的模糊示例。

作为一个新手,并且需要在两个进程之间共享一些信息(以文本形式) ,我应该使用 shmget()方法还是 mmap()?为什么?

65340 次浏览

两种方法都可行。mmap方法比 shmget方法限制更多一点,但是更容易使用。shmget是旧的 System V 共享内存模型,并且具有最广泛的支持。mmap/shm_open是实现共享内存的新 POSIX 方式,使用起来更加方便。如果您的操作系统允许使用 POSIX 共享内存,那么我建议使用它。

一些提示:

  • 如果你创造你的孩子通过 fork然后 mmapMAP_ANONYMOUS | MAP_SHARED是迄今为止最简单的方法-只有一个电话。然而,MAP_ANONYMOUS是一个 Linux 扩展 POSIX 未指定
  • 如果您独立地启动进程,但是可以为它们提供共享内存名称,那么 shm_open(+ ftruncate) + mmapMAP_SHARED就是两个/三个调用。在某些操作系统上需要 librt
  • 如果你的操作系统有 /dev/shm/,那么 shm_open相当于在 /dev/shm/中打开一个文件。

这与历史和未来方向有很大关系。

很久以前,unix-system V 和 BSD 有两个主要版本(在某种程度上也是相互竞争的)。SysV 有自己的 IPC 版本,包括大的3共享内存、信号量和消息队列。POSIX 出现了,试图团结一致。

因此,目前我们有两个版本-posx 共享内存、 MQ 和信号量以及 sysV 版本。只是让事情有点混乱的 sysV 版本是 还有的 posx 的一部分。

所以基本上你的问题是你想使用 Posix 还是 sysV 风格的共享内存?一般来说,大多数人采取长远的眼光,并选择 Posix,因为这似乎是通往未来的道路。但是,实际上,sysV 的东西是如此嵌入在这么多的系统,你必须有严重的怀疑,它将永远消失。

因此,消除长期的东西,归结起来就是什么对你的项目和你的品味有意义。一般来说,sysV 版本实际上更强大一些,但是它们有一个笨重的界面,大多数人在第一次接触时会觉得有点困惑。对于 sysV 信号量和消息队列尤其如此。就共享内存而言,可以说 sysV 和 posx 都很笨拙。SysV 版本带有笨重的 ftok和关键字,而 posx 最终需要设置多个调用和一些竞争条件。从外部来看,posx 版本的优势在于它们利用了文件系统,并且可以用标准命令行函数(比如‘ rm’)来维护,而不是像 sysV 需要的那样依赖于单独的实用程序(比如 ipcs)。

那么你应该使用哪种方法呢?通常,posx 版本。但是您真的应该熟悉 sysV 版本。它们的一些特性超出了 posx 版本的能力,您可能希望在特定情况下利用这些特性。