linux共享内存实际位于何处?

时间:2014-01-24 05:17:27

标签: c linux memory shared-memory

我只是想知道共享内存在Linux系统中的位置?它是在物理内存还是虚拟内存中?

我知道进程的虚拟内存发送框,它们不同于进程到进程,进程看不到彼此的内存,但我们可以使用IPC在进程之间传递数据。为了实现简单的场景,我刚刚创建了一个简单的共享内存程序,并尝试从shmat函数打印共享内存地址和值返回,但是这两个进程具有不同的地址但值相同。

这是写程序。

为write.c

#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdio.h>

int main() {

  key_t key=1235;
  int shm_id;
  void *shm;

  int *ptr = 83838;

  shm_id = shmget(key,10,IPC_CREAT | 0666);
  shm = shmat(shm_id,NULL,NULL);

  sprintf(shm,"%d",ptr);

  printf("Address is %p, Value is %p \n", (void *)shm, (void *)&ptr);
  printf("Shm value is %d \n", *(int *)shm);
  return;
}

这是读者程序。

read.c

#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdio.h>
#include <stdlib.h>

int main() {

  key_t key=1235;
  int shm_id;
  void *shm;

  int *p = (int *)malloc(sizeof(int));
  shm_id = shmget(key,10,NULL);
  shm = shmat(shm_id,NULL,NULL);
  if(shm == NULL)
  {
    printf("error");
  }
  sscanf(shm,"%d",p);
  printf("Address is %p %p %p %d\n",(void *)shm, (void *)p, (void *)&p, *p);
  printf("Shared value is %d \n", *(int *)shm);
  return 0;
}

如果有人能够详细解释过程如何看到相同的值,尽管有不同的地址,那会很棒吗?

此问题来自C pass void pointer using shared memory

感谢。

1 个答案:

答案 0 :(得分:22)

提交的所有内存都是物理内存。

但是,进程无法直接处理物理内存。它们具有内核将解析为物理地址的虚拟地址。设置共享内存区域时,多个进程会处理相同的物理内存位置。但是,虚拟地址可能不同。每个进程使用仅在其自己的上下文中接收的虚拟地址。两个虚拟地址都指的是相同的物理内存。


详细说明,在共享内存区域的情况下,同一物理内存地址可由多个进程同时寻址,因为这两个进程都具有指向相同物理地址的虚拟地址。

例如,请考虑以下事项:

  • 虚拟地址 V1 (在流程 T1 上下文中)
  • 虚拟地址 V2 (正在处理 T2 上下文)

都指向共享内存区域 这实际上是一个常见的物理地址 P

现在,
处理 T1 引用虚拟地址 V1
OR
处理 T2 引用虚拟地址 V2

将导致访问物理地址 P ,因为内核会将虚拟地址位置转换为内存中的相同物理位置。


例如,在下图中,物理内存 PFN4 由进程X和Y共享,分别使用 VPFN3 VPFN1 上下文。

Virtual memory maps for 2 processes