简体   繁体   中英

Segfault after accessing a structure in shared memory?

I have a problem with sharing values stored in a struct across processes. Below my code is simplified with only one process, which will increment the value num2 . Whenever the process ends, waitpid() writes the pid of the process to array . Again this is simplified, in my bigger project I have about 100 processes, which successively write their pid s in array . So every process sees the array . However, for every one of them the integer values in struct are different. Why?

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <semaphore.h>
#include <sys/shm.h>

typedef struct{
   int num;
   int num1;
   int num2;
   char *array;
} data;

void c_print(data *a);

int main(int argc, char *argv[])
{
   data *main_data;

   int pam_id=shmget(IPC_PRIVATE,sizeof(data), IPC_CREAT | IPC_EXCL | 0666);
   if (pam_id == -1)
       fprintf(stderr,"error");
   int k=shmat(pam_id,NULL,0);
   if (k==NULL)
       fprintf(stderr,"shmat error");
   main_data=malloc(sizeof(data));
   main_data->num = strtol(argv[1],NULL,10);
   main_data->num1 = strtol(argv[2],NULL,10);
   main_data->num2 = strtol(argv[3],NULL,10);

Without malloc below, accessing main_data causes a segfault . However, other processes can not see variables stored in struct except for array.

  main_data->array = malloc(main_data->num2*sizeof(char));

  main_data->array[0]=fork();
  if (main_data->array[0]==0){
      main_data->num2+=2;
      exit(9);
  } else {
      waitpid(-1,main_data->array[0],0);
      c_print(main_data);
      return 0;
  }
  return 50;
}

You should use k and not malloc() . The address of k is shared among the processes. I think you have misunderstood the shm api. Ie, replace main_data->array=...; with main_data->array=(void*)k; Each process will get a new copy of main_data . You need to use shmget with the num2*sizeof(char) .

The memory you wish to be shared should use shmget() and shmat() . malloc() will be allocated per process and will be initialized with a copy of the parents memory. If the num , num1 , num2 are private or const , then your data structure can use malloc() and the array should use shget and shmat . If you need both to be dynamically updated in all processes, then both must use shget() and shmat() .

Also, you should take care of data races.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM