为啥使用 shm_open?
Posted
技术标签:
【中文标题】为啥使用 shm_open?【英文标题】:Why use shm_open?为什么使用 shm_open? 【发布时间】:2014-09-12 13:23:39 【问题描述】:这样做有什么好处:shm_open
跟着mmap
?
为什么不创建一个常规文件,然后将 fd
传递给 mmap
?
我看不出shm_open
的优势——这些只是参考,不是吗?
我读过全家的男人。在我看来,“秘密”在映射操作中——文件“类型”似乎毫无意义。
任何指针都会很好,尤其是性能帐户。 我的上下文是一个(循环可重写)缓冲区(比如 128MB),它将不断被写入一个进程,并不断被另一个进程转储。
例如:this open/mmap 方法有什么问题。
编辑 准确地说,是以下哪一项优于另一项:
fd = open("/dev/shm/myshm.file", O_CREAT|O_RDWR, S_IRUSR | S_IWUSR);
mem = mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
对比
fd = shm_open("/myshm.file", O_RDWR|O_CREATE, S_IRUSR | S_IWUSR);
mem = mmap(...same as before...);
当我在 /dev/shm
fs 下使用常规 open
创建一个文件,并向其中转储 Gig 垃圾时,我的可用内存减少了 1G,而我的可用磁盘空间保持不变。
这两种方法有什么区别?
【问题讨论】:
试试吧。写入文件可能会慢一百倍。 【参考方案1】:如果您打开并 mmap() 一个常规文件,数据将最终出现在该文件中。
如果您只需要共享一个内存区域,而不需要持久化数据,这会产生额外的 I/O 开销,请使用 shm_open()。
这样的内存区域还允许您存储其他类型的对象,例如互斥锁或信号量,在大多数系统上,您无法将它们存储在 mmap() 的常规文件中。
【讨论】:
但是如果我在 /dev/shm fs 下创建文件呢?像这样,open("/dev/shm/myshm", "w")?使用 shm_open 有什么好处? 那么,如果您使用 shm_open 或 open,它几乎是一样的,但请记住这是特定于 linux 的。当存在标准方法时,这将是相当轻率的。如果 /dev/shm 也安装在非标准位置,则 shm_open 会小心定位。 感谢您指出可移植性问题。我们的产品作为虚拟机提供给客户,因此我们控制代码运行的分布,因此我们可以管理它。首先让我感到困惑的是无法在 /dev/shm fs 下创建逻辑目录。这是 glibc 的 shm_open 的产物,不是 fs 的问题 - 所以我要使用 open()。 @Trevor,请注意,根据 POSIX 标准:“名称中除前导斜杠字符之外的斜杠字符的解释是实现定义的。” 为什么不坚持使用标准 API 调用并简单地解决其限制,例如通过在文件名中使用下划线或其他特殊字符来分隔逻辑部分,而不是在/dev/shm
下创建目录?
你的建议确实是正确的 - 我仍然认为它。但是,例如,如果我想在 /dev/shm 下的“我们的”目录上执行和 inotify,我必须求助于在 /dev/shm 上执行 inotify - 并暴露给在此空间中注册的其他进程。想到的只是一个例子【参考方案2】:
这两个调用在现代 Linux 上本质上是等效的 - 第一种方法可用于从诸如 go(请参阅https://github.com/fabiokung/shm/blob/master/shm_linux.go)之类的语言访问 POSIX 共享内存,其中 POSIX 共享内存本机不可用 - 对于第一次调用会导致某些文件创建或 /dev 的其他操作系统/版本,它可能会有所不同/shm 只是不可用和/或性能可能较慢。路径合并的规则也可能会随着版本的 librt 演变
第一种方法称为内存映射文件 API(在标准库中支持)
第二个调用 POSIX 共享内存 API(需要 Linux 上的 librt aka libposix 作为依赖,它在内部构造路径并调用 open)
【讨论】:
【参考方案3】:看了shm_open
的源码,我可以说这两种方法差不多。
链接:https://code.woboq.org/userspace/glibc/sysdeps/posix/shm_open.c.html
shm_open 只是添加 shm_dir 前缀然后调用正常的open
系统调用,没什么特别的。
【讨论】:
以上是关于为啥使用 shm_open?的主要内容,如果未能解决你的问题,请参考以下文章
已使用 -L /lib -lrt -lpthread 未定义对“shm_open”的引用
当进程使用 shm_open() 时,Linux 内核如何分配内存指针?