views:

144

answers:

2

Hi there,

I am trying to share two different using one shared memory block using the shm.h library. I wrote the following example, where one shared memory block is created and is big enough to hold two integers. I then attach two integers to it and create two processes. The first process increments the first integer. The second process then prints out the value of two integers. But what happens is that both of the integers get incremented.

What am I doing wrong? I just started learning how to use shm library.

This is the code:

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

And this is the output:

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

I am running this on Gentoo Linux.

+1  A: 

Hi,

I noticed the following two lines:

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

and

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

Where shmID does not get changed between the two lines. This means that you are getting the same shared memory segment for data1 and data2. You'll need to create another shmId for data2 so that data2 gets a different shared memory segment.

Klarth
+3  A: 

Two integers aren't being incremented. One integer is being incremented but you are printing it out from two process addresses that map to the same shared memory.

The system memory manager plays some games behind the scenes to resolve shared memory. In two completely different processes it wouldn't be surprising to find that it mapped shared memory to two entirely different addresses in each process. The same thing is happening here. It is mapping data1 and data2 to process addresses 0x7fcd42a97000 and 0x7fcd42a96000 respectively but they actually point to the same thing in shared memory.

If I understand what you were trying to test, add and change the lines:

    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));
Duck
Thank you, that worked.
kkrizka