通过sys / shm.h共享多个变量

时间:2010-03-10 03:43:59

标签: linux gcc shared-memory

我正在尝试使用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 个答案:

答案 0 :(得分:2)

两个整数没有增加。一个整数正在递增,但是您要从映射到同一共享内存的两个进程地址打印出来。

系统内存管理器在幕后播放一些游戏来解析共享内存。在两个完全不同的过程中,发现它将共享内存映射到每个进程中的两个完全不同的地址就不足为奇了。同样的事情发生在这里。它将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 :(得分:1)

我注意到以下两行:

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

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

其中 shmID 在两行之间没有变化。这意味着您为 data1 data2 获取了相同的共享内存段。您需要为 data2 创建另一个 shmId ,以便 data2 获得不同的共享内存段。