I want to share memory among processes, which run independently instead of fork
.
I’ve read the man page for mmap
and shm_open
, and still confused about the usage.
- shared memory, in my mind, should be the mechanism of mapping virtual memory space among different processes, but Why
mmap
has thefd
argument? Does it mean the memory is actually shared through file? - Also, the
shm_open
seems to accept a filename as its argument, so it actually opens a file? - Since I have multiple independent processes, how should one inform other processes the physical memory address to share?
Could anyone give some example code for sharing memory among two process? Say, we have process producer
and a consumer
process, how would they communicate through the memory segment shared through mmap
?
Advertisement
Answer
Essentially, yes – on unix “everything is a file”. Well not quite, and it need not be an on-disk file, but in fact you can use an on-disk file if you want.
Formally
shm_open
accepts a name in its own namespace of named shared memory objects. They need to start with a single slash and should not contain another slash. You can name them however you want, but since it’s a global namespace, it’s preferable to generate random names (properly usingO_CREAT|O_EXCL
to check for collisions) and communicate the name via some other channel (like a state directory agreed upon in the configuration file used by the instance of your application) so that you don’t make it a system-wide singleton. In reality, on Linux and perhaps other common systems, the shared memory namespace is just a directory/dev/shm
that’s normally mounted as a non-persistent (in-memory) filesystem type to avoid wasteful writes to a disk.There is no physical memory address; it can vary and at times might not exist at all (if swapped out or when a page is clean and untouched). Nor are the virtual addresses of the mapped shared memory object common to different processes mapping it. What identifies the memory is the shared memory object file (referenced by an open file descriptor to it) an offset within it. So in order to use shared memory that’s independently mapped in different processes’ address spaces, you need to work with offsets from the base, not absolute pointers, adding the offset to the base whenever you need a pointer (e.g. to pass to synchronization primitives for mutexes, condition variables, semaphores, etc. in the shared memory, or for your own use).