计算机系统篇之虚拟内存(4):再探 mmap
Author:stormQ
Created: Friday, 13. November 2020 07:13AM
Last Modified: Tuesday, 17. November 2020 12:39PM
若参数 length 不是页大小的整数倍,那么 mmap 的行为?
参数length
不是页大小的整数倍的情形可以细分为两种:1)length
小于页大小;2)length
大于页大小,但不是页大小的整数倍。这两种情况在本质上没有什么区别。因此,我们以第一种情况作为研究示例,最终结论同样适用于第二种情况。
如果参数length
小于页大小时,我们通过研究以下问题来分析mmap
函数的真正行为。
-
实际创建的虚拟内存区域大小,是参数
length
的大小还是其他的? -
内存映射对象为普通文件时,修改该虚拟内存区域中大于
length
的部分,是否可共享? -
内存映射对象为普通文件时,修改该虚拟内存区域中大于
length
的部分,是否会被同步到普通文件中?
研究过程:
step 0: 准备研究示例
该示例首先使用mmap
函数创建一个可读写、共享的虚拟内存区域,内存映射对象为 Linux 系统中的普通文件——a.txt。然后,写一些数据到该虚拟内存区域中大于length
的部分。最后,调用msync
函数显式地同步这些数据到 a.txt 文件中。
源码,vm3_main.cpp:
#include <unistd.h>
#include <sys/mman.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
int main(int argc, char *argv[])
{
if (argc < 4)
{
printf("Usage, needed args: backed-file length offset\n");
return EXIT_FAILURE;
}
int fd = open(argv[1], O_RDWR);
if (-1 == fd)
{
perror("open failed, reason:");
return EXIT_FAILURE;
}
const auto length = atoi(argv[2]);
const auto offset = atoi(argv[3]);
auto addr = static_cast<int *>(mmap(NULL, length,
PROT_READ | PROT_WRITE, MAP_SHARED, fd, offset));
if (MAP_FAILED == addr)
{
perror("mmap failed, reason:");
return EXIT_FAILURE;
}
close(fd);
printf("page size:%ld bytes\n", sysconf(_SC_PAGE_SIZE));
const auto end = length + 10;
for (int i &