C - 如果无法删除共享内存段,会发生什么情况



根据我的观察,如果我在不删除共享内存段的情况下终止进程,则该共享内存段将保留在那里,/dev/shm/xxxx,甚至没有其他进程使用它。这是否意味着内存泄漏?(重新启动机器后它会消失)为什么 linux 不提供一种机制来维护共享内存上的引用计数,然后系统可以在没有进程使用它时将其删除。

由于进程可能会崩溃,或者我只是未能捕获一些异常......无论如何,当进程异常终止时,我很有可能无法删除该共享内存段。

我的用例:我正在运行几个工作进程,它们共享相同的内存段进行通信。并且没有主节点来协调事物。该策略是最后一个退出节点将关闭共享内存段。

顺便说一下,我使用的是boost::interprocess而不是系统级别的shm_open,但我认为它们的行为应该是相同的。

Posix 标准要求(强调):

创建共享内存对象时,共享内存

对象的状态(包括与共享内存对象关联的所有数据)将一直存在,直到取消链接共享内存对象并且所有其他引用都消失为止。未指定名称和共享内存对象状态在系统重新引导后是否仍然有效。

换句话说,共享内存对象基本上类似于临时文件;它们旨在持久化,至少在会话期间是这样。使用特定命名共享内存对象的所有进程都可能崩溃,您仍然可以启动新进程并恢复共享内存对象的内容。

由于 Linux 试图与 Posix 标准保持一致,因此它以相同的方式实现共享内存对象,这意味着除非手动清理,否则它们会一直存在(直到重新启动)。

不再被任何活动进程使用的共享内存对象并不完全是内存泄漏,因为如果存在内存压力(并且启用了交换),它将迅速被换出。但是,最好自己定期清理共享内存对象。有多种策略可以执行此操作,具体取决于应用程序的确切性质。

一个简单的(但绝不是通用的)解决方案是在知道不需要打开共享内存对象后立即取消链接。取消链接对象会有效地删除其名称,以便无法再shm_open它,但只要某个进程具有对它的开放引用,取消链接的对象就会一直存在。(操作系统确实保留引用计数;但是,名称计为引用,因此只要名称存在,对象也会保留引用计数。创建临时文件的应用程序也经常使用相同的策略。

相关内容

最新更新