地址视图

地址视图

Content #

地址视图的巧妙之处就在于,一个在物理内存上存放的对象,被映射在了三个虚拟地址上。前面我们学习地址映射的时候知道,一个物理地址可以被映射到多个虚拟地址,这个映射方式在同一个进程内同样适用。例如下面的代码:

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <unistd.h>

#define PAGE_SIZE 4096
int main() {
    int fd = memfd_create("anonymous", MFD_CLOEXEC);
    ftruncate(fd,PAGE_SIZE);
    char* shm0 = (char*)mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
    char* shm1 = (char*)mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
    char* shm2 = (char*)mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
    sprintf(shm0 ,"hello colored pointer");
    printf("%s\n",shm1);
    printf("%s\n",shm2);
    sprintf(shm1 ,"wow!");
    printf("%s\n",shm0);
    printf("%s\n",shm2);
    close(fd);
    munmap(shm0,PAGE_SIZE);
    munmap(shm1,PAGE_SIZE);
    munmap(shm2,PAGE_SIZE);
    return 0;
}

使用以下命令,编译并执行这个程序:

$ gcc -Wall -D_GNU_SOURCE multi_mmap.c -o multi
$ ./multi

上面的例子先在内存中创建了一个匿名文件,然后将这个匿名文件映射到 shm0, shm1,shm2 三个虚拟地址上。当我们修改 shm0 时,shm1 和 shm2 的内容也会跟着变化。地址视图也是用了同样的原理,三个地址视图映射的是同一块物理内存,映射地址的差异只在第 42-45 位上。这样一个对象可以由三个虚拟地址访问,其访问的内容是相同的。

Viewpoint #

From #

mmap的用法