I'm playing around with some code that requires communication between a parent and a forked child process. I've created an int in shared memory before the fork, but any changes I make with the child process don't seem to affect the int when accessed by the parent process. Here's a piece of code that illustrates my problem.
int * shared = mmap(NULL, sizeof(int), PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
pid_t child;
int childstate;
if((child=fork())==0){
*shared = 1;
exit(0);
}
waitpid (child, &childstate, 0);
printf("%d",*shared);
Although the child process sets the value of 'shared' to 1, this program outputs 0.
In my actual program a struct will be shared instead of an int, but if I can figure out this code snippet, I think the rest should fall into place.
I'm by no means an experienced programmer, and I'm a bit unfamiliar with C. I've spent hours trying to figure this out and read dozens of pages which say it should be a simple process. To be honest, it's been a heavy blow to my self esteem :) . I'm sure I'm just missing some small detail - can anybody point it out to me? Thanks in advance for your time.
The anonymous file-mapped shared memory provides an inheritable shared memory, as in: the child process inherits the shared memory.
mmap method is a little bit more restrictive then shmget , but easier to use. shmget is the old System V shared memory model and has the widest support. mmap / shm_open is the new POSIX way to do shared memory and is easier to use. If your OS permits the use of POSIX shared memory then I would suggest going with that.
The mmap() function establishes a mapping between a process' address space and a stream file. The address space of the process from the address returned to the caller, for a length of len, is mapped onto a stream file starting at offset off.
mmap works by manipulating your process's page table, a data structure your CPU uses to map address spaces. The CPU will translate "virtual" addresses to "physical" ones, and does so according to the page table set up by your kernel. When you access the mapped memory for the first time, your CPU generates a page fault.
Your problem is the flags passed into mmap()
, you want MAP_SHARED
.
int * shared = mmap(NULL, sizeof(int), PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0);
Works as expected with the code below
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <stdio.h>
int main(void) {
int * shared = mmap(NULL, sizeof(int), PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0);
pid_t child;
int childstate;
printf("%d\n", *shared);
if((child=fork())==0){
*shared = 1;
printf("%d\n", *shared);
exit(0);
}
waitpid (child, &childstate, 0);
printf("%d\n",*shared);
}
Output:
0
1
1
mmap man page may help you if you haven't already found it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With