3
votes

I want to use POSIX Shared Memory and my question is about the usage of msync() and munmap() after calling mmap(MAP_SHARED).

  1. Are the changes made to the shared memory segment of one process visible to the shared memory segment of the other process without the use of msync()?
  2. Are the changes made to the shared memory segment only visible in the file after msync()?
  3. Are the changes saved when the shared memory segment is unmapped without the prior usage of msync()?

I have the impression msync() is only useful to apply the changes to underlying file and not to the shared memory.

1

1 Answers

3
votes

POSIX

See msync(2):

  • Implementation may decide that changes are not visible in other processes and in underlying file until msync() is called with MS_ASYNC or MS_SYNC.
  • Implementation may decide that changes are dropped if msync() was not called before close()/munmap().

This allows old implementations to use separate caches for memory mappings (a.k.a page cache) and file I/O (a.k.a buffer cache).

Modern implementations

Modern implementations (e.g. modern Linux) usually implement "unified virtual memory model" which uses the same cache for memory mappings and I/O. It's not required by POSIX or SUSv3.

In such implementations:

  • Changes are visible in other processes and underlying file immediately.
  • Changes are not dropped if msync() was not called before close()/munmap().
  • MS_ASYNC is a no-op.
  • MS_SYNC is just like fsync().

In Linux, msync() is just another interface to fsync() and nothing more. See msync(2) manual page and this thread.

Reference

See "The Linux Programming Interface", section "49.4.4 Memory Protection and File Access Mode Interactions".