How to Two Mmap on Same /Dev File

How does mmap work when 2 programs map the same file

So, what happens when 2 programs map the same file? Are there 2 entries in the page table, one for each program?

In modern operating systems, each process has its own page table for its memory, that may point to pages of physical memory shared with other user and kernel processes.

With MAP_SHARED, this mapping is shared: updates to the mapping are visible to other processes that map this file, and are carried through to the underlying file. The file may not actually be updated until msync(2) or munmap() is called.

This seems very interesting, but there are numerous caveats:

  • The actual pages mmapped by both processes for the same file may reside at the same address or at a different address in each process, storing pointers into this shared memory may not allow the other process to use them as they might point to inconsistent addresses.

  • The implementation may use the same physical memory pages for both mappings or not: for subtile reasons (cache strategies, out of sync reading...), even if it is the same physical memory, modifications done by one process to its memory may not be immediately reflected in the memory of the other process.

So the modification may or may not be visible to the other processes mmapping the file nor reading it via read or the FILE* stream API.

If one of the processes calls msync(), the modifications should be visible in all maps and for all yet unread portions of the file, bearing in mind that the FILE* streaming APIs may have buffered some data in internal unshared buffers: modifications in this area will not be reflected.

Conclusion: it is risky and unreliable to use these mechanisms to implement inter process communication. The behavior may depend on system specific characteristics such as the OS strategies, the CPU and cache architectures, the type of RAM in use, the clock speed, and who knows what else. It is safer to rely on proven APIs that may indeed be implemented using mmapped memory, but only if it is know to provide the correct semantics.

Using mmap to map different segments in a file

You should be able to use lseek to move the current file offset. Then, the next write() will be to that location. Alternatively, it may be easier to just mmap multiple different file descriptors to the same file. See for instance, this question: Can we TWO MMAP on same /dev file .

mmap same file, same physical memory?

When you map a file the pages come from the kernel page cache which maintains the kernel view of the file. There is only ever one view of the same file in the kernel. When you map the file more than once (regardless from which process), the mapped pages are the very same physical pages from the kernel page cache.

Otherwise, it would be prohibitively expensive to maintain different pages of memory in sync when one process modifies its MAP_SHARED file mapping.

In other words, processes A and B together share the same N bytes of physical memory used to map the same file.

How would I assign multiple MMAP's from single file descriptor?

There is no need for three separate mmaps. Simply mmap once, then compute the base pointer for each plane relative to the base pointer of the whole map.

Edit: You need something like this:

unsigned char *y = mmap(...); /* map total size of all 3 planes */
unsigned char *u = y + y_height*y_bytes_per_line;
unsigned char *v = u + u_height*u_bytes_per_line;

How to map two virtual adresses on the same physical memory on linux?

Since Linux kernel 3.17 (released in October 2014) you can use memfd_create system call to create a file descriptor backed by anonymous memory. Then mmap the same region several times, as mentioned in the above answers.

Note that glibc wrapper for the memfd_create system call was added in glibc 2.27 (released in February 2018). The glibc manual also describes how the descriptor returned can be used to create multiple mappings to the same underlying memory.

Memory Mapping the same file multiple times?

You can use MAP_PRIVATE in order to get a private copy-on-write mapping of the underlying file. You can use MAP_SHARED in order to get a view of the underlying file. I do not know what happens if you have the same region mapped in MAP_PRIVATE mappings and MAP_SHARED mappings at the same time, but I suspect writes to either mapping cause a copy.

In order to sync with disk, you want to use msync. On most systems, multiple MAP_SHARED mappings will give you a piece of memory, nominally backed by disk, that is shared among processes. I'm not sure whether this behaviour is specified or merely a happy consequence of the typical implementation.

What happens if two distinct processes use mmap to map the same region of file (one with MAP_SHARED, another with MAP_PRIVATE)?

Then A gets the file mapped and B gets the file mapped but any writes will not be written back to the file.

From the manpage:

It is unspecified whether changes made to the file after the mmap() call are visible in the mapped region.



Related Topics



Leave a reply



Submit