Remove posix shared memory when not in use?

user964970 picture user964970 · Nov 14, 2012 · Viewed 8.7k times · Source

Is there any way, linux specific or not, to have posix shared memory segments (obtained with shm_open()) removed when no process is using them. i.e. have them reference counted and have the system remove them when the reference becomes 0

A few notes:

  • Establishing an atexit handler to remove them doesn't work if the program crashes.

  • Currently, the linux specific way, I embed the pid in the segment name, and try to find unused segments by walking /dev/shm in an external program. Which has the drawback of having to periodically clean them up externally in a rather hackish way.

  • As the program can run multiple copies, using a well defined name for the segment that the program reuses when it starts up is not feasible.

Answer

Hristo Iliev picture Hristo Iliev · Nov 18, 2012

If there is a point in your program's execution when it is well known, that all processes that need to open the shared memory segment have already done so, you can safely unlink it. Unlinking removes the object from the global namespace but it sill lingers around as long as there is at least one process that keep its file descriptor open. If a crash occurs after that point, the file descriptor is automatically closed and the reference count is decremented. Once no open descriptors to the unlinked shared memory block remain, it is deleted.

This is useful in the following scenario: a process creates a shared memory block, unlinks it and then forks. The child inherits the file descriptor and can use the shared memory block to communicate with the parent. Once both processes terminate, the block is automatically removed as both file descriptors get closed.

While unlinked, the shared memory block is unavailable for other processes to open it. Meanwhile, if one use shm_open() with the same name as the unlinked block, a new and completely different shared memory block would be created instead.