Linux shared memory: shmget() vs mmap()?

A lot of this has to do with history and future directions.

Once upon a time there were two main (and somewhat competing) versions of unix - system V and BSD. SysV had its own versions of IPC, including the big 3 - shared memory, semaphores, and message queues. POSIX came along to try and unite things.

So at present we have two versions - posix shared memory, MQs, and semaphores and the sysV versions. Just to make things a little more confusing the sysV versions are also part of posix.

So basically your question is do you want to use Posix or sysV style shared memory? In general most people take the long term view and opt for Posix because that seems to be road to the future. But, realistically, sysV stuff is so embedded in so many systems you have to have serious doubts that it will ever go away.

So, eliminating the long term stuff, it comes down to what makes sense for your project and your tastes. In general the sysV versions tend to actually be somewhat more powerful but they have an clunky interface that most people find a little bewildering at first contact. The is particularly true of sysV semaphores and message queues. In terms of shared memory it can be argued both sysV and posix are awkward. The sysV versions carries the clunky ftok and key stuff while the posix ends up taking multiple calls and some race conditions to set up. From the outside, the posix versions have an advantage in that they utilize the file system and can be maintained with standard command line functions like 'rm' rather than relying on separate utility programs (e.g. ipcs) that sysV requires.

So which should you use? As a rule, the posix versions. But you should really familiarize yourself with sysV versions. They have some features that go beyond the capabilities of the posix versions which you may want to take advantage of in specific situations.


Both methods are viable. mmap method is a little bit more restrictive then shmget, but easier to use. shmget is the old System V shared memory model and has the widest support. mmap/shm_open is the new POSIX way to do shared memory and is easier to use. If your OS permits the use of POSIX shared memory then I would suggest going with that.

Some hints:

  • If you create your children via fork then mmap with MAP_ANONYMOUS | MAP_SHARED is by far the easiest way - just one call. MAP_ANONYMOUS is however a Linux extension not specified by POSIX.
  • If you start the processes independently, but can supply them with a shared memory name then shm_open (+ ftruncate) + mmap with MAP_SHARED is two/three calls. Requires librt on some OSes.
  • If your OS has /dev/shm/ then shm_open is equivalent to opening a file in /dev/shm/.