如何在同一共享内存段中正确拥有多个变量

how to have correctly multiple variables in same shared memory segment

我试图在同一个内存段中有 2 个整数。我的代码如下:

int main()
{
  int *a;
  int *b;
  int id;
  id = shmget(IPC_PRIVATE,10,0666);
  a = (int *) shmat(id, (void*)0, 0);
  b = (int *) shmat(id, (void*)0, 0);
  *a = 5;
  *b = 10;
  printf("%d\n",*a);
  printf("%d\n",*b);
}

这会打印两次 10。谁能解释一下为什么会发生这种情况以及如何解决?

额外的问题:如果我有 char * 而不是 int 是否有必要执行 malloc(sizeof(char)*10) 或 shmat 调用以某种方式完成工作?

提前致谢!

首先,您总是希望尽可能使用 malloc 而不是共享内存。 即使在进行 IPC 时,简单的管道通常效率更高。

回到你的问题,下面是对你的代码的一些解释

int main()
{
  int *a;
  int *b;
  int id;

  /* 'shmget' creates a shared memory segments of size 10,
     basically reserving 10 bytes of RAM/Swap. This memory is not 
     accessible in your virtual memory yet */   
  id = shmget(IPC_PRIVATE,10,0666);

  /* `shmat` maps the shared memory from above and makes it accessible in
     your virtual memory. `a` points to the beginning of the memory segment */ 
  a = (int *) shmat(id, (void*)0, 0);

  /* Here we map the same shared memory again into a different place in the
     virtual memory. But even if `a` and `b` points to different memory
     addresses, those addresses are backed by the same segment in RAM/Swap */  
  b = (int *) shmat(id, (void*)0, 0);

  *a = 5;
  *b = 10; /* because `*a` and `*b` are backed by the same RAM/Swap, */ 
           /* this will allso overwrite `*a`                        */

  printf("%d\n",*a);
  printf("%d\n",*b);
}

要解决这个问题,您基本上有两种选择。要么有两个共享内存段,一个用于a,一个用于b。或者你使一个段足够大以容纳 ab 以指向段中的不同位置:

第一个解决方案:

/* This uses two segments */
int *a;
int *b;
int id1;
int id2;
id1 = shmget(IPC_PRIVATE,sizeof(int),0666);
id2 = shmget(IPC_PRIVATE,sizeof(int),0666);
a = (int *) shmat(id1, (void*)0, 0);
b = (int *) shmat(id2, (void*)0, 0);

第二种解决方案:

/* This uses one segments */
int *a;
int *b;
int id;
/* Allocate enough memory for 2 int */
id = shmget(IPC_PRIVATE, 2*sizeof(int), 0666);
/* Map that memory into virtual memory space */
a = (int *) shmat(id, (void*)0, 0);
/* `a` points to the first int in a sequence of 2 ints, let `b` point to 
   the next one. */
b = a + 1;

与往常一样,为简洁起见,此代码省略了错误检查。添加错误检查留作 reader.

的练习。

关于额外的问题,malloc 或任何共享内存函数都不关心您要在分配的内存中存储什么。他们只是给你一个 char 的序列。计算您需要多少 char 是您的工作。 (顺便说一句 sizeof(char) 总是 1)