Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Do I need to use shm_unlink on a shared memory object?

I've written a server (GNU C++ / Linux) which runs continuously, and occasionally executes small stand-alone programs to do work. In order to efficiently get data to the worker programs, the server creates and maps a shared memory object (code abbreviated for clarity):

int fd = shm_open("/shm_file", O_CREAT | O_TRUNC | O_RDWR, S_IRUSR | S_IWUSR);
ftruncate(...);
data = mmap(...);
// etc...
launchWorker(...);   // Start the worker program

The worker program then opens this shared memory in a similar way (except read-only, without the O_CREAT and O_TRUNC, i.e. we assume it already exists).

When the worker finishes, it closes the file descriptor, unmaps with munmap(...) and unlinks with shm_unlink(...).

At this point, there is a file "/dev/shm/shm_file" which I guess is the shared memory object. Unlinking in the worker doesn't remove it because the server still has it open. When the server unlinks it, the file system object disappears. This behavior is consistent with the man page for shm_open / shm_unlink, and works fine for my server/worker case.

However, now I'd like the workers to be able to share certain data between themselves, and possibly (for testing) do this when the server is not running.

If I create a shared memory object in one worker program and DO NOT use munmap(...) and shm_unlink(...) when it exits, I note that the shared memory object remains in /dev/shm, and I can open it again in another worker program. This is handy.

However, is it safe to do this? (i.e. repeatedly run a program which maps shared memory, then doesn't unmap/unlink it)? I'm guessing that the unmap() doesn't matter as the memory mapping will vanish with the process, but what about the shm_unlink? Given that the OS decided when to delete the object based on whether it is still being used, if I fail to call shm_unlink() every time, will this cause a leak of some kind?

like image 298
Jeremy Avatar asked May 21 '14 21:05

Jeremy


People also ask

What is the role of Ftruncate () when you create a shared memory object?

When a new shared-memory object is created, the size of the object is set to zero. To set the size, you use ftruncate()—the very same function used to set the size of a file —or shm_ctl().

What is Shm_unlink?

Description: The shm_unlink() function removes the name of the shared memory object specified by name. After removing the name, you can't use shm_open() to access the object. This function doesn't affect any references to the shared memory object (i.e., file descriptors or memory mappings).

Is MMAP shared memory?

Using mmap on files can significantly reduce memory overhead for applications accessing the same file; they can share the memory area the file encompasses, instead of loading the file for each application that wants access to it. This means that mmap(2) is sometimes used for Interprocess Communication (IPC).


1 Answers

The only leak is that the file will stay even after the last process that opened it exists.

But since that was the intent in this case it is not really a leak as such.

The files in /dev/shm behave just like regular files (because they are).

This means that the name can be removed (using unlink or shm_unlink) but the file data will remain until the name is gone and the last process using it stops doing so (having the file open or it's content mmap:ed counts as using it).

But there is only the one file, no matter how many times you open and/or mmap it.

And when a process exits all open file descriptors are closed, and all memory mappings are removed.

like image 170
perh Avatar answered Sep 22 '22 23:09

perh