2

我正在尝试使用 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 上运行它。

4

2 回答 2

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));
于 2010-03-10T04:25:08.763 回答
1

我注意到以下两行:

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

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

其中shmID不会在两行之间更改。这意味着您为data1data2获得了相同的共享内存段。您需要为 data2 创建另一个shmId,以便data2获得不同的共享内存段。

于 2010-03-10T03:59:41.613 回答