Ziq*_*Liu 2 c linux shared-memory multiprocessing
根据我的观察,如果我在不删除共享内存段的情况下终止我的进程,则该共享内存段将只保留在那里,在 中/dev/shm/xxxx,甚至没有其他进程正在使用它。 这是否意味着内存泄漏?(在我重新启动机器后它会消失)为什么 linux 不提供一种机制来维护共享内存上的引用计数,然后系统可以在没有进程使用它时将其删除。
由于进程可能会崩溃,或者我只是未能捕捉到一些异常......无论如何,当进程异常终止时,我很有可能无法删除该共享内存段。
我的用例:我正在运行几个共享相同内存段进行通信的工作进程。并且没有主节点来协调事情。策略是最后一个退出节点将关闭共享内存段。
顺便说一下,我使用的boost::interprocess是系统级别shm_open而不是系统级别,但我认为它们的行为应该是相同的。
Posix 标准要求(强调):
创建共享内存对象时,共享内存对象的状态(包括与共享内存对象关联的所有数据)会一直存在,直到共享内存对象取消链接且所有其他引用都消失为止。未指定名称和共享内存对象状态在系统重新启动后是否保持有效。
换句话说,共享内存对象基本上就像临时文件;它们旨在持久化,至少在会话期间是这样。所有使用特定命名共享内存对象的进程都可能崩溃,您仍然可以启动一个新进程并恢复共享内存对象的内容。
由于 Linux 试图与 Posix 标准保持一致,因此它以相同的方式实现共享内存对象,这意味着除非手动清理它们,否则它们会一直存在(直到重新启动)。
不再被任何活动进程使用的共享内存对象并不完全是内存泄漏,因为如果存在内存压力(并且启用了交换),它将迅速被换出。但是,自己定期清理共享内存对象是个好主意。有多种策略可以这样做,具体取决于您的应用程序的确切性质。
一个简单的(但绝不是通用的)解决方案是在您知道没有新进程需要打开共享内存对象后立即取消链接。取消链接对象有效地删除了它的名称,这样它就不再可能了shm_open,但是只要某个进程有一个对它的开放引用,取消链接的对象就会一直存在。(操作系统确实保留了一个引用计数;但是,只要名称存在,对象就可以作为引用计数。)创建临时文件的应用程序也经常使用相同的策略。