Sharing memory mappings under Linux
-
02-07-2021 - |
Question
Motivation
I'd like to write a pair of programs where one program reads data and transfers it into an internal format and the other program transfers the internal format into something else. As an excercise, I want to code the interaction between these programs without the use of pipes. I rather like to use signals and shared memory.
What I want
I have programs A and B where A calls B. How can I
- Create a memory block from program A
- Call program B from program A, giving it the information about where to find the memory block
- Use the memory block from both programs.
More specific, A decodes a custom video format and places a single uncompressed frame into a shared buffer. B reads from the buffer and encodes it into an output strean. The decoder decodes up to 100 frames per second which is about 500 MiB/s memory traffic. Pipes turned out to be slow since the data has to be copyied much too often and the buffers aren't exactly big.
What I think might work
My idea is to use mmap(NULL,len,PROT_READ|PROT_WRITE,MAP_SHARED|MAP_ANONYMOUS,-1,0)
to create a section of shared memory. The problem is, that the manpage of execve(2)
states:
Memory mappings are not preserved (mmap(2)).
So, how can I share that memory with the other program? Is it a better idea to put both functionality into one program and use fork
instead?
Solution
*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.