mmap
标准 C99(或 C11)规范中不存在。它是在 POSIX 中定义的。
因此,假设您有一个 POSIX 系统(例如 Linux),您可以首先open(2)用于读写的文件:
int myfd = open("hello.txt", O_RDWR);
if (myfd<0) { perror("hello.txt open"); exit(EXIT_FAILURE); };
然后您可以使用以下命令获取文件的大小(和其他元数据)fstat(2):
struct stat mystat = {};
if (fstat(myfd,&mystat)) { perror("fstat"); exit(EXIT_FAILURE); };
现在文件的大小是mystat.st_size
.
off_t myfsz = mystat.st_size;
现在我们可以调用mmap(2)我们需要share the mapping(能够通过虚拟地址空间)
void*ad = mmap(NULL, myfsz, PROT_READ|PROT_WRITE, MAP_SHARED,
myfd, 0);
if (ad == MMAP_FAILED) { perror("mmap"); exit(EXIT_FAILURE); };
然后我们可以覆盖第一个字节(并且我们检查该文件中的第一个字节确实是H
既然你答应了):
assert (*(char*ad) == 'H');
((char*)ad) = 'R';
我们可能会打电话msync(2)以确保磁盘上的文件立即更新。如果我们不这样做,它可能会稍后更新。
特别是对于非常大的映射(特别是那些比可用 RAM 大得多的映射),我们可以协助内核(及其页面缓存)并给出提示疯狂的维斯(2) or posix_madvise(3)...
请注意,即使在close(2). Use munmap
& mprotect
or mmap
with MAP_FIXED
在相同的地址范围上更改它们。
在 Linux 上,你可以使用proc(5)查询地址空间。所以你的程序可以读取(例如之后fopen
, using fgets
循环中)伪/proc/self/maps
文件(或/proc/1234/maps
对于 pid 1234 的进程)。
BTW, mmap
被使用dlopen(3);它可以被调用很多次,我的manydl.c程序表明,在 Linux 上你可以拥有数十万个dlopen
-ed 共享文件(数十万个内存映射)。