views:

807

answers:

6

I know about "mmap", but as far as i know if i want to share memory allocated by a parent process and accessed it by a client process i need to create a temporary file.

But this file will continue to exist if the processes die.

I was educated to never leave garbage behind. Both in real life and in programming.

The solution should work on Linux, FreeBSD and Solaris.

+2  A: 

This article is a very good starting point for shared memory.

However, I'd recommend that you use a pipe instead generally, so as to avoid race conditions and all the mental overhead of concurrency. When you open a child process, its stdin and stdout are file descriptors that you can read and write to from the parent process.

Will
Sorry this is a small and important piece of my software and i need to be able to exchange data sets as fast as possible. And no i'm not scared about concurrency and race conditions. I love high speed concurrency programming. But here i must call an external child process as it might load unsafe plugins that shouldn't be able to crash the main application.
Lothar
Sounds like you're on top of things and the article I linked to will make sense.You'll end up copying anything the parent reads from the shared buffer into a buffer private to the parent, and then verify it, obviously. And at some point, you'll be trying to do in userland what the kernel does for you with pipes, and you might not find pipes so slow themselves.
Will
A: 

Allocate Memory in Parent. Use this memory both in parent and Child. Give the responsibility of freeing the memory to the parent. Make the parent wait (wait system call) on the child. Parent frees the memory before exiting.

Alternatively to be on safer side, before the child exits check if the parent is alive or not. If not, free the memory in child itself.But this won't work if there can be multiple child.

You can use first few bits of memory to track the number of process using this memory. Whenever a process starts using memory it increment this count and before exiting it decrements the count.Plus if the count becomes 0 , Free the memory.

There is yet another method.Write a function ownMalloc which sits on top of system malloc (or whichever function you uses). This keeps track of all allocated memory and also the processes which uses it. It periodically goes through the the different chunks allocated and frees the chunk not in use.

Duleb
+1  A: 

Mmap usually supports "anonymous" mode which does not create any garbage. It works on LInux, according to man page works on Solaris, I am not sure about FreeBSD - look at the man page and search for MAP_ANON or MAP_ANONYMOUS.

ondra
And I should add that before MAP_ANONYMOUS, the trick used to by to unlink() the file just after the mmap. This allow the parent and child processes to use the shared memory.
ondra
Hmm if i use MAP_ANONYMOUS what file descriptor should i pass if not that of a file? Okay i can try to generate a "/tmp/dummy" file just to use a handle (to which no data is ever written). But it still leaves some garbage.
Lothar
You pass `-1` as the file descriptor when using `MAP_ANONYMOUS`.
caf
Well and what do i pass in the child process? Something doesnt work this way.
Lothar
You must first allocate the memory area using mmap() in the parent process and only then fork() the children. If the children are not 'real' children or if there is some problem with allocating this before the fork(), you would have to go with shm_get or shm_open, which, unfortunately, don't allow for 'automatic' cleanup of unused resources by the OS.
ondra
But when i load the new process image for the child, the fork does not help me as everything except the handles is dying and a mmap does not return me a new handle to inherit it to the child process. Sorry i still don't get how this works for parent <-> child interaction.
Lothar
It works for parent/child interaction where you *don't* use `exec()` in the child.
caf
In your situation, you can use `shm_open()`, and have the child call `shm_unlink()` immediately after it has exected the `shm_open()` (the memory region will only be actually destroyed once all the processes that have it mapped have unmapped it or exited).
caf
A: 

Use POSIX shm_open(3) and related functions to map memory not backed by a file. The file descriptor returned by shm_open() should be automatically closed if parent and child cease to exist, but I'm not 100% sure if that's always the case. Maybe someone else can shed more light on that?

Inshallah
Sorry "shm" and the posix semaphores are so broken on FreeBSD (shm by design - as i found out after a conversation on the FreeBSD mailing list).
Lothar
A: 

Named Pipes should do for you as mentioned above. You can use two pipes (if possible) :

  1. parentpid_childpid -- Parent writes and child reads
  2. childpid_parentpid -- Child writes and parebt reads.

This works for me. Please mention if you have any special senarios to consider.

Vaibhav
A: 

Allocate the memory in Parent process, keep on wait till the child process executes or let him do some other tasks. Once the child process is over then it will return to the parent process, Deallocate the memory there.

If the parent process needs to be stopped before child(Child is said to be orphaned in this case) then use the exec() which will start child process as a new process.

Sachin Chourasiya