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

ska*_*iya 10 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;
}
Run Code Online (Sandbox Code Playgroud)

这是读者计划.

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;
}
Run Code Online (Sandbox Code Playgroud)

如果有人可以请详细解释如果有不同的地址,流程如何看到相同的价值,那将是很好的?

这个问题来自使用共享内存的C pass void指针.

谢谢.

The*_*ist 22

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

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


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

例如,请考虑以下事项:

  • 虚拟地址V1(在进程T1上下文中)
  • 虚拟地址V2(在进程T2上下文中)

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

现在,
进程T1引用虚拟地址V1

进程T2引用虚拟地址V2

当内核将虚拟地址位置转换为内存中的同一物理位置时,将导致访问物理地址P.


例如,在下图中,物理存储器PFN4由进程X和Y 在其各自的上下文中使用VPFN3VPFN1共享.

2个进程的虚拟内存映射

  • 虚拟地址仅在其进程上下文中有效。一旦发生上下文切换并且不同的进程正在运行,加载的新页表可能不包含导致段错误的特定地址的物理位置映射。即使碰巧物理内存位置确实映射到新进程中的相同虚拟地址,也不能保证指向与原始进程中相同的物理内存位置。通过这个 [**answer**](http://stackoverflow.com/a/20348391/319204) 正确理解您面临的问题。 (2认同)