访问共享进程内存时出现段故障(核心转储)

时间:2019-05-02 17:06:52

标签: c interprocess

我试图让两个子进程将两个随机整数写入共享内存,然后让父进程读取它们。 每当尝试访问父进程中的数组元素时,我都会遇到分段错误,因此似乎无法验证写作。

尝试在写完之后立即从子进程的内存中读取内容。

#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
#include <time.h>
#include <stdlib.h>
#include <sys/ipc.h>
#include <sys/shm.h>

int main(){
  srand(time(NULL)); 
  int pid2;
  key_t key = 12345;
  int shmid = shmget(key, 2 * sizeof(int), IPC_CREAT|IPC_EXCL|0666);
  int *array = (int *)shmat(shmid, 0, 0);
  int pid1 = fork();
//write first array element
  if (pid1 == 0){
    int n1 = rand() % 10;
    printf("I'm process number 1, my pid is %d and my number is %d\n", getpid(), n1);
    array[0] = n1;
    return 1;
  }
  if (pid1 > 0){
    int pid2 = fork();
    if (pid2 == 0){
//write second array element
      int n2 = rand() % 10;
      printf("I'm process number 2, my pid is %d and my number is %d\n", getpid(), n2);
      array[1] = n2;
      return 1;
    }
  }
  waitpid(pid1, NULL, 0);
  waitpid(pid2, NULL, 0);
//segmentation fault happens here
  printf("%d\n", array[0]);
  return 0;
}

1 个答案:

答案 0 :(得分:3)

您不是要从shmget检查有效的返回值。

if (shmid<0){printf("shmget error");exit(1);};

如果这样做,您会发现分配无效,因为该key_t已经存在,请尝试另一个-或生成您自己的唯一密钥:

key_t key = 1; 

key_t key = ftok("megasuperrandom",'a');

根据“ man ftok”:

  

通常,尽力而为的尝试将给定的proj_id字节组合在一起,   索引节点编号的低16位,以及   设备号转换为32位结果。碰撞很容易发生,因为   / dev / hda1上的文件和/ dev / sda1上的文件之间的示例。

因此,您可能想遍历某些对象,直到找到一个可行的对象为止,以代替使用ftok()。

此外,如果您希望孩子们使用不同的随机数,则可能需要使用不同的随机函数,或将srand()移至每个孩子。

此外,您可能需要检查“ man waitpid”。它不会等到进程退出,而只会等待状态更改-这是不可预测的。如果要确保退出该过程,则必须检查返回状态。