Skip to content
Advertisement

How is shmat() etc. implemented in the Linux kernel. Is there any other way to share memory?

with mmap(), processes must inherit the mapping from a parent to share memory. is there a way to share memory between processes that don’t share a parent? shmat() seems to be the best solution, but it requires clean up if the processes didn’t detach the memory on exit/die.

Domain sockets are close to sharing memory…

Advertisement

Answer

With mmap, processes must inherit the mapping from a parent if you use anonymous memory. However, if the mapping is backed by a file then there is no such requirement. shmat, aka System V shared memory, isn’t without problems either – traditionally it used to be a limited resource, and one needs to play with sysctl and root to raise the limits.

With mmap both processes can open and map the same file, and then unlink the file. Now, when all the processes exit the file will also be automatically removed. Or it can be unlinked in the beginning – a server process can then share open file descriptors to clients via unix sockets.

Of course using mmap with file backing will mean that you will need actual disk space to back the mapping, and the mapping will be flushed to the disk.

If you want a mapping that is not backed by a disk file, you can use POSIX shared memory objects:

System V shared memory (shmget(2), shmop(2), etc.) is an older shared memory API. POSIX shared memory provides a simpler, and better designed interface; on the other hand POSIX shared memory is somewhat less widely available (especially on older systems) than System V shared memory.

On Linux these are essentially just files in /dev/shm but the portable way to use these is to create and open them with shm_open. Again, with this, even if the shared memory object was unlinked with shm_unlink, a process that has the shared memory object opened can send open file descriptors to it via unix domain sockets, and the receiver can use the descriptor to map the shared memory into its process space.

Thus something like:

fd = shm_open("/my_shared_mem", O_RDWR|O_CREAT, 0700);
ftruncate(fd, 64 * 4096);
shared_mem = mmap(NULL, 64 * 4096, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0)

in the first process, second can open with O_RDWR and doesn’t need to truncate. To remove the shared memory object, use shm_unlink:

shm_unlink("/my_shared_mem");

which will immediately unlink it from /dev/shm; those processes that have it opened can continue using it; the object is actually removed only when every process stop using it.

Advertisement