Ошибка сегментации (дамп ядра) при доступе к общей памяти процесса - PullRequest
2 голосов
/ 02 мая 2019

Я пытаюсь, чтобы два дочерних процесса записали два случайных целых числа в общую память, а затем родительский процесс прочитал их.Кажется, я не могу проверить запись, поскольку получаю ошибку сегментации всякий раз, когда пытаюсь получить доступ к элементу массива в родительском процессе.

Попытка чтения из памяти в дочернем процессе сразу после записи ничего не делает.

#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 Ответ

3 голосов
/ 02 мая 2019

Вы не проверяете правильное возвращаемое значение из 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 битов номера индекса и младшие 8биты номера устройства в 32-битный результат.Коллизии могут легко произойти, например, между файлами в / dev / hda1 и файлами в /dev/sda1.

Так что вы, вероятно, захотите перебрать некоторые, пока не найдете работающий, в качестве альтернативыиспользовать ftok ().

Кроме того, если вы хотите, чтобы у детей были разные случайные числа, вы, вероятно, захотите использовать другую случайную функцию или переместить srand () для каждого ребенка.

Также вывозможно, стоит проверить "man waitpid".Он не ожидает завершения процесса, а только ожидает изменения состояния, что непредсказуемо.Если вы хотите убедиться, что процесс завершен, вам придется проверить статус возврата.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...