简体   繁体   English

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

[英]Segmentation fault (core dumped) when accessing shared process memory

I'm trying to have two child processes write two random integers to a shared memory, then have the parent read them. 我试图让两个子进程将两个随机整数写入共享内存,然后让父进程读取它们。 I cant seem to validate the writing as I get a segmentation fault whenever I try to access an array element in the parent process. 每当尝试访问父进程中的数组元素时,由于出现分段错误,我似乎无法验证编写。

Trying to read from memory in child process right after writing does nothing. 写入后立即尝试在子进程中从内存中读取任何内容。

#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;
}

You're not checking for a valid return value from shmget. 您不是在从shmget检查有效的返回值。

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

If you did, you would find that the allocation was invalid, because that key_t already exists, try another one - or generate your own unique one: 如果这样做,您会发现分配无效,因为该key_t已经存在,请尝试另一个-或生成自己的唯一密钥:

key_t key = 1; 

or 要么

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

As per "man ftok": 按照“男人的福克”:

Typically, a best-effort attempt combines the given proj_id byte, the lower 16 bits of the inode number, and the lower 8 bits of the device number into a 32-bit result. 通常,尽力而为尝试将给定的proj_id字节,inode编号的低16位和设备编号的低8位组合为32位结果。 Collisions may easily happen, for example between files on /dev/hda1 and files on /dev/sda1. 冲突可能很容易发生,例如/ dev / hda1上的文件与/ dev / sda1上的文件之间。

So you will probably want to loop over some until you find one that works, as an alternative to using ftok(). 因此,您可能想遍历某些对象,直到找到一个可行的对象为止,以替代使用ftok()。

Also, if you want the children to come up with different random numbers, you will likely want to use a different random function, or move srand() to each child. 另外,如果您希望孩子们使用不同的随机数,则可能需要使用不同的随机函数,或将srand()移至每个孩子。

Also, you might want to check "man waitpid". 另外,您可能要检查“ man waitpid”。 It doesn't wait until the process exits, it only waits for a changed state - which is unpredictable. 它不会等到进程退出,而只会等待状态更改-这是不可预测的。 If you want to make sure that the process exited, you will have to check the return status. 如果要确保该过程已退出,则必须检查返回状态。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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