использование shm_open для копирования целых чисел из родительского процесса в дочерний процесс - PullRequest
0 голосов
/ 19 апреля 2020

Я пытаюсь скопировать целые числа из родительского процесса в дочерний процесс. Многие вопросы такого рода перенаправлены на использование другого метода IP C. Это не будет работать для моего случая. Решение ДОЛЖНО использовать <sys/shm.h>. Это часть гораздо большей программы. Я инициализирую размер, указатель, pid и имя памяти следующим образом:

          const int SIZE = 4*sizeof(int);
          const char *name = "OS";
          pid_t pid;
          int shm_fd;
          void *ptr;

Я вызываю fork

pid = fork();

Родительский процесс потребляет целые числа примерно так

                  /* open the shared memory segment */
                  shm_fd = shm_open(name, O_RDONLY, 0666);
                  if (shm_fd == -1) {
                          fprintf(stderr,"open shared memory failed\n");
                          exit(-1);
                  }

                  /* now map the shared memory segment in the address space of the process */
                  ptr = mmap(0,SIZE, PROT_READ, MAP_SHARED, shm_fd, 0);
                  if (ptr == MAP_FAILED) {
                          fprintf(stderr,"Map failed in parent\n");
                          exit(-1);
                  }
                  printf("Parent got mapped pointer: %p\n",ptr);
                  /* now read from the shared memory region */
                  printf("Parent has received:");
                  for(int i=0; i < SIZE/sizeof(int); i++)
                        printf(" %d ", *(int *)(ptr +i));
                  printf("\n");

                  /* remove the shared memory segment */
                  if (shm_unlink(name) == -1) {
                          fprintf(stderr,"Error removing %s\n",name);
                          exit(-1);
                  }
                  printf("parent done\n");

Дочерний код выдает целые числа, например, так:

                  printf("In Child process. I am the producer: my pid=%d\n",getpid());
                  time_t t;
                  srand(time(&t));
                  int integers[SIZE];
                  printf("Generating random integers: ");
                  for(int i=0; i < SIZE/sizeof(int); i++){
                          int value = (rand() -49) %49;
                          integers[i] = value;
                          printf(" %d ", value);
                  }
                  printf("\n");


                  /* create the shared memory segment */
                  shm_fd = shm_open(name, O_CREAT | O_RDWR, 0666);
                  if (shm_fd == -1) {
                          fprintf(stderr,"open shared memory failed\n");
                          exit(-1);
                  }

                  /* configure the size of the shared memory segment */
                  ftruncate(shm_fd,SIZE);

                  /* now map the shared memory segment in the address space of the process */
                  ptr = mmap(0,SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0);
                  if (ptr == MAP_FAILED) {
                          fprintf(stderr,"Map failed in child\n");
                          return -1;
                  }
                  printf("Child got mapped pointer: %p\n",ptr);
                  void *ptr2=ptr;//back up the pointer for later use
                  /* Now write to the shared memory region. Increment the value of ptr after each write. */
                  memcpy(ptr, integers, sizeof(int));
                  memcpy(ptr+1,integers+1, sizeof(int));
                  memcpy(ptr+2,integers+2, sizeof(int));
                  memcpy(ptr+3,integers+3, sizeof(int));

                  printf("Child has sent: ");
                  for(int i=0; i < SIZE/sizeof(int); i++)
                          printf(" %d ", *(int *)(ptr2+i));
                  printf("\n");

Это простая программа-производитель IP C, созданная потребителем, но по какой-то причине, когда я запускаю программу, мой вывод неверен. Например, когда я генерирую набор целых чисел, я получаю

In Parent process. I am the consumer: my child pid=19187
In Child process. I am the producer: my pid=19187
Generating random integers:  8  10  37  48
Child got mapped pointer: 0x7f91c9c09000
Child has sent:  807733768  3155210  12325  48
Parent got mapped pointer: 0x7f91c9c09000
Parent has received: 807733768  3155210  12325  48
parent done

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

1 Ответ

1 голос
/ 19 апреля 2020

Боюсь, в арифметике указателей есть опечатка c.
*(int *)(ptr +i) должно быть *((int *)ptr+i)
*(int *)(ptr2+i) должно быть *((int *)ptr2+i)

Это означало «Увеличение с i байтов, затем считать целочисленным указателем» вместо »считать целочисленным указателем, а увеличение с i элементов» .

Существует та же проблема с memcpy(ptr+i, это должно быть memcpy((int *)ptr+i,.

Совет: немедленно объявите ptr с правильным типом, это позволит избежать множества опасных приведений .

Кстати, я не вижу никакой синхронизации между дочерним письмом и родительским чтением.
Добавление уродливого sleep(1); (не делайте этого в реальной жизни!) До того, как printf("Parent has received:");, кажется, дает что-то правильное.

И другим способом, в зависимости от планирования процесса, вызов shm_open(name, O_RDONLY, 0666); в родительском элементе может завершиться ошибкой, если дочерний элемент еще не вызвал shm_open(name, O_CREAT | O_RDWR, 0666); (сегмент еще не существует).

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