在this线程建议OP使用mmap()
而不是shmget()
来获取Linux中的共享内存。 我访问了this页面和this页面以获取一些文档,但第二个页面给出了关于mmap()
的一个模糊示例。Linux共享内存:shmget()vs mmap()?
作为一个新手,需要在两个进程之间共享一些信息(文本形式),我应该使用shmget()
方法还是mmap()
?为什么?
谢谢
鲍勃
在this线程建议OP使用mmap()
而不是shmget()
来获取Linux中的共享内存。 我访问了this页面和this页面以获取一些文档,但第二个页面给出了关于mmap()
的一个模糊示例。Linux共享内存:shmget()vs mmap()?
作为一个新手,需要在两个进程之间共享一些信息(文本形式),我应该使用shmget()
方法还是mmap()
?为什么?
谢谢
鲍勃
两种方法都可行。 mmap
方法有一点限制,然后shmget
,但更容易使用。 shmget
是旧的System V共享内存模型并具有最广泛的支持。 mmap
/shm_open
是执行共享内存的新POSIX方法,更易于使用。如果你的操作系统允许使用POSIX共享内存,那么我会建议使用它。
一些提示:
fork
然后mmap
与MAP_ANONYMOUS | MAP_SHARED
是迄今为止最简单的方式 - 只需一个电话。shm_open
(+ ftruncate
)+ mmap
与MAP_SHARED
是两/三个调用。在某些操作系统上需要librt
。/dev/shm/
则shm_open
相当于在/dev/shm/
中打开文件。很多这些都与历史和未来的方向有关。
曾几何时,有两个主要的(有点竞争的)UNIX版本 - 系统V和BSD。 SysV拥有自己的IPC版本,包括大型3共享内存,信号量和消息队列。 POSIX走过来试图团结一切。
所以目前我们有两个版本 - posix共享内存,MQs,信号量和sysV版本。只是为了让事情变得更加混乱,sysV版本也是也是 posix的一部分。
所以基本上你的问题是你想使用Posix或sysV风格的共享内存?一般来说,大多数人都会采取长期观点并选择Posix,因为这似乎是通向未来的道路。但是,实际上,sysV的东西如此嵌入到如此多的系统中,你必须怀疑它会永远消失。
因此,消除长期的东西,它归结为什么对您的项目和您的口味有意义。一般来说,sysV版本实际上更加强大一些,但它们有一个笨拙的界面,大多数人在第一次接触时会觉得有些困惑。 sysV信号量和消息队列尤其如此。就共享内存而言,可以认为sysV和posix都很尴尬。 sysV版本携带笨重ftok
和关键的东西,而posix结束了多次通话和一些竞争条件设置。从外部看,posix版本的优势在于它们利用文件系统,并且可以使用标准命令行功能(如“rm”)进行维护,而不是依赖sysV要求的单独实用程序(例如ipcs
)。
那你应该使用哪一种?通常,posix版本。但是你应该真正熟悉sysV版本。它们的某些功能超出了您可能想要在特定情况下利用的posix版本的功能。
你能解释为什么你认为System V版本更强大? –
强大的可能是错误的词。富勒功能也许?例如,sysv信号量范围从正数到负数,可以增加或减少,可以撤消操作,如果进程死亡,可以报告最后一个进程对它们进行操作(如果扩展到报告线程,这会更有用),在内核中存在,因此您不必混淆共享内存,并且可以一次性创建整个系列。 sysv MQ具有msgtypes,它允许许多进程轻松共享相同的队列并只处理特定的类型。 Posix MQ总是读取最早的消息 – Duck
谢谢你的所有有用的建议。现在我不会使用fork。 – BowPark
但在mmap中修改内存时,硬盘上的文件会被自动修改?所以你经常对这个文件写文章? – BowPark
'/ dev/shm'是你的RAMdisk。如果使用文件支持的共享内存“mmap”,则该文件位于实际磁盘上,然后由操作系统来安排更新。通常,在停止使用映射或分页守护程序决定将页面交换出去之前,映射文件将不会更新。您可以通过调用'msync'来强制更新,这是在使用希望写入磁盘的文件支持的映射时推荐的做法。 –