为什么要使用SysV或POSIX共享内存而不是mmap()?

11

当需要在OS X 10.4及以上的操作系统中,从子进程向父进程传递大量数据(200kb+)时,我研究了Unix上的共享内存,特别是System V和POSIX共享内存机制。随后我意识到,可以使用mmap()函数与MAP_ANON和MAP_SHARED标志(如果不介意创建一个普通文件,也可以只使用MAP_SHARED标志)来完成类似的工作。

我的问题是,有没有理由不直接使用mmap()函数?它似乎更简单,内存仍然是共享的,并且如果使用MAP_ANON,则不必创建实际的文件。我可以在父进程中创建文件,然后fork()和exec()子进程,在子进程中使用它。

第二个问题是,什么情况下这种方法不足以满足需求,必须使用SysV或POSIX共享内存机制?请注意,我打算使用管道进行同步,因为我需要用于其他通信,即父进程通过管道请求数据,子进程将其写入共享内存,并通过管道响应已准备好。没有多个读者或写者参与。可移植性不是首要考虑因素。


如果我使用MAP_ANON,我可以在父进程中创建文件,然后fork()和exec()子进程并在子进程中使用它。你设法完成了这个吗?据我所知,没有办法让mmap()的内存在exec之后继续存在。它可以在fork之后继续存在,但不能在exec之后。 - Lassi
4个回答

8

如果存在父子进程关系,使用mmap是完全可以的。

sysv_shm是最初的Unix实现,允许相关和不相关的进程共享内存。posix_shm标准化了共享内存。

如果您在没有mmap的posix系统上,则应使用posix_shm。如果您在没有posix_shm的Unix上,则应使用sysv_shm。如果您只需要与父/子进程共享内存,则可以使用可用的mmap。


1
你不能在没有mmap的情况下使用posix_shm,那部分是无意义的。不过你在第一段是正确的,当你没有父/子关系时,posix_shm可以启用mmap。 - Leon Timmermans
如果不相关的进程通过实际文件约会,它们可以使用mmap共享内存。 - jxh

1
如果记忆没有出错的话,使用SysV/POSIX而不是mmap的唯一原因是可移植性。特别是旧的Unix系统不支持MAP_ANON。然而,Solaris、Linux、BSD和OS X都支持它,因此实际上没有理由不使用mmap。

1

shm 在 Linux 中通常是通过一个 /dev/shm 文件实现的,该文件会被 mmap 映射,因此性能应该是相当的 -- 如果我知道可移植性不是问题(正如你所说的那样),我会选择使用 mmap(带有 MAP_ANONMAP_SHARED,就像你提到的那样)来简化操作。


memfd_create()现在也在几乎所有支持的Linux内核版本中实现。 - Lassi

0

文档所知,若想使用Xlib/XCB共享内存图像,则必须使用 SYSV 共享内存。


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