mmap file between unrelated processes
Two independent processes can use mmap(2) to share access to the kernel disk block cache holding the file data:
1) Process A opens a file, makes the file the desired size and creates an mmap(2) window into the file.
2) Process B opens the same file and creates an mmap(2) window into the same file.
3) Now, the same kernel block cache data exist simultaneously in both processes. Either process can modify the data and that data is instantaneously available in the other process.
This is the issue the MAP_SHARED flag is intended to provide.
Sharing Pointers Between Multiple Forked Processes
All data you want to share has to be in the shared segment. This means that both the pointers and the strings have to be in the shared memory.
Sharing something which includes pointers can be cumbersome. This is because mmap doesn't guarantee that a given mapping will end up in the required address.
You can still do this, by two methods. First, you can try your luck with mmap and hope that the dynamic linker doesn't load something at your preferred address.
Second method is to use relative pointers. Inside a pointer, instead of storing a pointer to a string, you store the difference between the address of the pointer and the address of the string. Like so:
char **keys= mmap(NULL, ...);
char *keydata= (char*) keys + npointers * sizeof(char*);
strcpy(keydata, firstring);
keys[0]= (char*) (keydata - (char*) &keys[0]);
keydata+= strlen(firststring)+1;
When you want to access the string from the other process, you do the reverse:
char **keys= mmap(NULL, ...);
char *str= (char*) (&keys[0]) + (ptrdiff_t) keys[0];
It's a little cumbersome but it works regardless of what mmap returns.
Sharing memory mappings under Linux
*nix systems have several APIs for shared memory:
- BSD: use
mmap()
. To share memory between unrelated processes, you associate it to a file. You can also share memory between related processes usingMAP_ANONYMOUS
andfork()
ing (but make sure to use -1 asfd
for portability). - System V: (some people really dislike this one) use
shmget()
to create/get a reference to a shared memory area, attach to it viashmat()
, detach viashmdt()
, mark for deletion withshmctl()
. You identify shared memory areas by a key, which should be unique. - POSIX: use
shm_open()
thenmmap()
from the returned file descriptor.
Share std::map between processes with mmap()
This does not work because although you placed the container object into the shared memory, the elements are still allocated from the heap and thus they are not accessible by other processes.
You need a custom allocator that allocates elements in the shared memory. See Creating maps in shared memory for how it is done.
Note that the string class you use must also allocate memory from the shared memory.
In other words, you cannot have pointers to heap memory in the shared memory, because heap memory is not shared between processes. std
classes have an allocator template argument, the default one allocates memory from the heap. This needs to be changed to a shared memory allocator to be able to share such objects via shared memory.
Related Topics
Get Address Family from Socket. Linux
Single Process Maximum Possible Memory in X64 Linux
Format Number with Commas in C++
How Do Objects Work in X86 at the Assembly Level
How to Compare Multiple Strings Inside an If Statement
Qt: Resizing a Qlabel Containing a Qpixmap While Keeping Its Aspect Ratio
How to Statically Link Standard Library to My C++ Program
May I Take the Address of the One-Past-The-End Element of an Array
What's the Difference Between "Static" and "Dynamic" Schedule in Openmp
Differencebetween "New" and "Malloc" and "Calloc" in C++
Press Anykey to Continue in Linux C++
Headers Including Each Other in C++
Is There a Difference Between Universal References and Forwarding References
When Is It Best to Use the Stack Instead of the Heap and Vice Versa
How to Solve "Unresolved Inclusion: <Iostream>" in a C++ File in Eclipse Cdt