linux - 在 shm_open 和 mmap 之间使用 fstat

标签 linux posix shared-memory

我正在将现有的 Win32 代码移植到 Linux。在 Windows 上,我有一个“主”进程,即“读取器”,它创建一个共享内存对象,然后等待一些“从属”进程,即“写入器”,将数据放入共享内存中进行处理。

主进程:Win32 实现依赖于 CreateFileMapping( INVALID_HANDLE_VALUE, [...] 后跟 MapViewOfFile 中指定的共享内存大小 si >CreateFileMapping 调用。将 0 作为最后一个参数传递给 MapViewOfFile 可确保映射所有共享内存。在 Linux 上,经过一些谷歌搜索后,我得出结论,我应该使用 shm_open + ftruncate + mmap.

Slave进程:Win32实现与Master进程几乎相同,只是CreateFileMappingOpenFileMapping代替,VirtualQuery 可用于获取共享内存的大小。

在 Linux 上,我遇到了一个问题:“从属”进程必须以某种方式“等待”ftruncate 调用在“主”进程中完成。他们不能自己执行 ftruncate,因为他们还不知道共享内存的大小。

“从属”进程在 fstat beetwen shm_openmmap 上轮询是否可以?或者这是不好的做法,如果是,是否有另一种映射“好”尺寸的方法?

编辑:

暂时不想直接使用File System。我喜欢这样一个事实,即我可以通过使用将在 2 个平台上工作的“名称”创建一个“命名共享内存对象”,如 "/MySharedMemName42" 并且不想关心文件的位置。如果看起来不现实,我可能会改变主意。

我知道在使用共享内存时,主进程和从进程必须合作。他们通过写入/读取内存来做到这一点。 “问题”是如果存在竞争(ftruncate 在主机中迟到),shm_open/mmap 可能会导致从机中出现 SIGBUS。我测试了“fstat polling”是否有效,但想知道它是否被视为一个糟糕的 hack,或者是处理比赛的正确方法。

最佳答案

如果我理解正确,Windows CreateFileMapping 调用是 UNIX 节“shm_open+ftruncate+maybe-mmap”的原子 版本,因此在 UNIX 上有可能客户端可以在共享内存大小合适之前访问它。

因此,您建议使用 fstat 没问题。这是officially supported通过 POSIX 共享内存选项。您的设计似乎可以容忍共享内存区域是否存在的轮询,因此轮询它的正确大小(或至少 st_size > 0)也应该没问题。

或者,您可以在打开期间使用共享内存区域的模式(O_CREAT|O_EXCL 和 0600),并在准备就绪时fchown — 您的从属进程,取决于 UID 和 GID,在内存准备好之前,会因 ENOENT 或 EACCES 而失败。这又是一个“轮询”选项。您还可以在调整大小后重命名共享内存本身(通过 Linux 的 /dev/shm/),但这是一种非 POSIX 便利。

(现在,如果您的下属是主人的 child ,那么您可以依靠古老的 *NIX 进程继承技术并切换到未命名的共享内存...)

关于linux - 在 shm_open 和 mmap 之间使用 fstat,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20501290/

相关文章:

linux - 安装 Ghost 博客

linux - 我如何将需要另一个文档的二进制文件添加到命令行?

mysql - 是否可以将我的数据库导入另一台服务器?

c - 我在哪里可以找到 struct proc_dir_entry 的定义

c - POSIX pthread 编程

c++ - 调用 shmat 两次

windows - 如何在内核转储中获取 Section 对象的内容

c - 使用 `shm_open()` 在两个进程之间共享一个带有指针的结构

linux - 命令脚本将文件识别为目录

从消息队列接收后无法使用shm_open