Совместное использование нескольких переменных через sys / shm.h - PullRequest
2 голосов
/ 10 марта 2010

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

Что я делаю не так? Я только начал изучать, как использовать библиотеку shm.

Это код:

#include <sys/sem.h>
#include <sys/ipc.h>
#include <sys/types.h>
#include <sys/shm.h>

#include <stdio.h>
#include <unistd.h>

int main() {
  // Declare variables
  int shmID;
  int *data1;
  int *data2;

  // Create a shared memory segment  
  if((shmID=shmget(IPC_PRIVATE, 2*sizeof(int), 0666 | IPC_CREAT))<0)
    {
      fprintf(stderr,"Problem initializing shared memory\n");
      perror("main");
      return -1;
    }

  if((data1=shmat(shmID,NULL,0))==(int *)-1)
    {
      fprintf(stderr,"Problem attaching memory 1\n");
      perror("main");
      return -1;
    }

  if((data2=shmat(shmID,NULL,0))==(int *)-1)
    {
      fprintf(stderr,"Problem attaching memory 2\n");
      perror("main");
      return -1;
    }

  printf("%p %p\n",data1,data2);
  (*data1)=0;
  (*data2)=0;
  if(fork()) 
    { // Process 1 will be the incrementer
      for(int i=0;i<100;i++)
    {
      (*data1)++;
      printf("IN:  %d\n",(*data1));
      sleep(1);
    }
      printf("IN DONE\n");
    }
  else
    {
      while((*data1)<50)
    {
      printf("OUT: %d %d\n",(*data1),(*data2));
      sleep(1);
    }
      printf("OUT DONE\n");
    }
}

И это вывод:

0x7fcd42a97000 0x7fcd42a96000
IN:  1
OUT: 1 1
IN:  2
OUT: 2 2
IN:  3
OUT: 3 3

Я использую это в Gentoo Linux.

Ответы [ 2 ]

2 голосов
/ 10 марта 2010

Два целых числа не увеличиваются. Увеличивается одно целое число, но вы распечатываете его с двух адресов процессов, которые отображаются в одну и ту же разделяемую память.

Менеджер системной памяти играет некоторые игры за сценой, чтобы разрешить совместную память. В двух совершенно разных процессах было бы не удивительно обнаружить, что он отображал общую память на два совершенно разных адреса в каждом процессе. То же самое происходит и здесь. Это сопоставление data1 и data2 для обработки адресов 0x7fcd42a97000 и 0x7fcd42a96000 соответственно, но они фактически указывают на одно и то же в общей памяти.

Если я понимаю, что вы пытались проверить, добавьте и измените строки:

    printf("%p %p\n", data1, data2);

    (*data1) = 0;
    (*data2) = 0;

    int *data3 = data2 + 1; //points 1 int beyond data1 & data2

    (*data3) = 5; //will always print 5

    //............
    printf("OUT: %d %d %d\n", (*data1), (*data2), (*data3));
1 голос
/ 10 марта 2010

Я заметил следующие две строки:

if((data1=shmat(shmID,NULL,0))==(int *)-1)

и

if((data2=shmat(shmID,NULL,0))==(int *)-1)

Где shmID не изменяется между двумя строками. Это означает, что вы получаете один и тот же сегмент совместно используемой памяти для data1 и data2 . Вам нужно создать еще один shmId для data2 , чтобы data2 получил другой сегмент общей памяти.

...