Matteo Pagliarello
Matteo Pagliarello

Reputation: 191

How can i use shared memory on a fork with shmget?

I'm study the shared memory on C but i don't understand how to use the share memory when i want to change the value on the child process. I worte this simple code but it doesn't work as i expexted, did i miss something?

CODE:

    #include <sys/ipc.h>
#include <sys/shm.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/wait.h>
#include <sys/sem.h>
#include <stdbool.h>
int create_shared_memory(){
    return shmget(IPC_PRIVATE,sizeof(int),0644 | IPC_CREAT);
}
int get_shared_memory(int key){
    return shmget(key,sizeof(int),0644 | IPC_CREAT);
}
int* attachd_shared_memory(int key){
    return shmat(key,NULL,0);
}

int main(int argc, char const *argv[])
{
    printf("\nSono il PID: %d di PID: %d\n",getpid(),getppid());
    int sh_id = create_shared_memory();
    int *result = attachd_shared_memory(sh_id);
    
    int x = 5;
    result = &x;
    printf("Puntatore: %i Numero(x): %d\n",*result,x);
    *result = 9;
    printf("Puntatore: %i Numero(x): %d\n",*result,x);
    if (!fork())
    {
        int sh2_id = get_shared_memory(sh_id);
        int* result2 = attachd_shared_memory(sh2_id);
        int y = 4;
        result2 = &y;
        printf("Sono il PID: %d di PID: %d \n",getpid(),getppid());
        printf("ID: %d %d\n",sh_id,sh2_id);
        printf("Puntatore: %i Numero(x): %d\n",*result2,x);
        exit(0);
    }
  
      for (int i = 0; i < 2; i++)
         {
            printf("\nHo finito di aspettare:%d  sono il padre: %d\n",wait(NULL),getppid());
         }
           shmctl(sh_id, IPC_RMID, NULL);
    printf("Puntatore: %i Numero(x): %d \n",*result,x);
    return 0;
}

Thank for the advice, i have to read better the basic of c but this satisfy my request. SOLUTION:

int create_shared_memory(){
    return shmget(IPC_PRIVATE,sizeof(int),0644 | IPC_CREAT);
}
int get_shared_memory(int key){
    return shmget(key,sizeof(int),0644);
}
int* attachd_shared_memory(int key){
    return shmat(key,NULL,0);
}

int main(int argc, char const *argv[])
{
    printf("\nSono il PID: %d di PID: %d\n",getpid(),getppid());
    int sh_id = create_shared_memory();
    int *result = attachd_shared_memory(sh_id);
    
    int x = 5;
    *result = x;
    printf("Puntatore: %i Numero(x): %d\n",*result,x);
    *result = 9;
    printf("Puntatore: %i Numero(x): %d\n",*result,x);
    if (!fork())
    {
       *result = 4;
        printf("Sono il PID: %d di PID: %d \n",getpid(),getppid());
       
        exit(0);
    }
  
      for (int i = 0; i < 2; i++)
         {
            printf("\nHo finito di aspettare:%d  sono il padre: %d\n",wait(NULL),getppid());
         }
           shmctl(sh_id, IPC_RMID, NULL);
    printf("Puntatore: %i Numero(x): %d \n",*result,x);
    return 0;
}

Upvotes: 0

Views: 401

Answers (1)

Barmar
Barmar

Reputation: 781210

You're overwriting the pointer to the shared memory when you do

result = &x;

Now result points to the private memory of x instead of the shared memory segment.

The child has the same problem when it does

result = &y;

You can't turn private memory into shared memory by assigning its address to result. So don't do those assignments.

Just use *result as the shared memory. Anything you assign to that in one process will be visible in the other.

So use

*result = x;

to store the value of x in the shared memory, and

y = *result;

to retrieve it.

Upvotes: 1

Related Questions