我只是想知道共享内存在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。
感谢。
答案 0 :(得分:22)
提交的所有内存都是物理内存。
但是,进程无法直接处理物理内存。它们具有内核将解析为物理地址的虚拟地址。设置共享内存区域时,多个进程会处理相同的物理内存位置。但是,虚拟地址可能不同。每个进程使用仅在其自己的上下文中接收的虚拟地址。两个虚拟地址都指的是相同的物理内存。
详细说明,在共享内存区域的情况下,同一物理内存地址可由多个进程同时寻址,因为这两个进程都具有指向相同物理地址的虚拟地址。
例如,请考虑以下事项:
都指向共享内存区域 这实际上是一个常见的物理地址 P 。
现在,
处理 T1 引用虚拟地址 V1
OR
处理 T2 引用虚拟地址 V2
将导致访问物理地址 P ,因为内核会将虚拟地址位置转换为内存中的相同物理位置。
例如,在下图中,物理内存 PFN4 由进程X和Y共享,分别使用 VPFN3 和 VPFN1 上下文。