Shared memory for fork

2020-03-29 03:14发布

问题:

I want to create a shared memory between two process. I used fork(). A child tries to change this shared memory and mother creates another child so new child tries to change same memory so on. here is my code in C programing. (ubuntu)

mylist ch=NUL; 
f=fork();
if(!f){
        pba=shmget(KEYSHM,sizeof(char),0); /*created shared memory*/
        ch=(mylist *) shmat(pba,0,0);
        ch->name=ugur;
        ch->surname=cedric;
...do something...
}
else{
        if(ch)
        printf("this is top of mylist %s"ch->name);
.......do something
}

It never writes ch->name. why? I created a shared memory. Why parent process cannot read?

回答1:

For the memory to be shared, both the parent and the child must access the same shared memory.

You have two options, the simpler and the harder:

  • Create and attach to the shared memory before forking. Both parent and child automatically have access to the same shared memory.

  • Fork first, and then both parent and child must attach to the shared memory separately. Once the processes have forked, they no longer share memory, and in particular, anything allocated in the child is not accessible in the parent.

You need to allocate more than 1 character of shared memory to store useful strings such as names.



回答2:

You have a race condition, what if the parent runs before the child , and you try to access ch-> before the child has placed anything there ?

You also allocate only 1 byte(sizeof(char)) but you're trying to treat that as a pointer to a struct - you need to allocate enough space for mylist - unless you've done so erlier. You'd need the IPC_CREAT flag to shmget somewhere too.



回答3:

if first run parent process can't access the ch->name because ch->name=ugur; doesn't run yet.I recommend see this tutorial for shared memory and this pdf file .
one solution that i think get shared memory before fork() and use it in child and parent.



回答4:

The way you have your code written, ch will point to some shared memory but ch itself (i.e. the pointer) is not shared. Because the assignment of ch happens only in the child, the parent will continue to see ch as NULL.

You have two ways to fix this:

  1. Set up the shared memory prior to the fork.
  2. Have both the parent and child open the same shared memory.

When working with records in shared memory, you need to make sure that all the data for that record exists in shared memory. For example, in this code:

    ch->name=ugur;
    ch->surname=cedric;

It appears that mylist::name is a char *. If ch points to a record in shared memory, this is only going to place the pointers to the names in shared memory. Unless you take specific steps to put those strings into shared memory, they will be in regular memory and will probably not be accessible to other programs.



回答5:

If i create and attach the shared memory before forking then i can not check if the shared memory is NULL or not. It initiates while attaching.



回答6:

You also used 0 for your flags, which specify things like access rights and if the shared memory segment should be created. In other words, you didin't give yourself read or write access and didn't specify for the segment to be created if it doesn't exist yet.