linux内存映射边读边写,Linux系统编程——内存映射与写时复制

本文介绍了内存映射的基本概念,包括两种主要类型——文件映射和匿名映射,以及它们如何在不同进程中共享或私有化。重点讲解了写时复制技术在私有映射中的应用,并通过一个简单的C语言程序示例展示了如何使用`mmap`系统调用来实现私有文件映射。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

基本概述

内存映射就是将虚拟内存中的一块区域与磁盘上的对象建立关联以初始化虚拟内存区域的内容。有两种映射

文件映射:讲一个文件的一部分直接映射到调用进程的虚拟内存中

匿名映射:一个映射没有对应的文件(也可以理解成一个内容总是被初始化为零的虚拟文件的映射)

一个进程的映射中的内存可以与其他进程中的映射共享,当两个或者多个进程共享相同的物理分页时候,每个进程都可以对其做修改和读取,此时就会出现一致性问题,由此,映射的方法又可以分为共享和私有:

私有映射:在映射内容上发生的变更对其他进程不可见,对于文件映射来说即为不会在物理页面(底层)更改。此时就会利用写时复制技术来实现

共享映射:在映射内容上发生的变更会对所有共享同一个映射的其他进程可见

#include

void *mmap(void *addr,size_t length,int prot,int flags,int fd,off_t offset);

//成功时候返回映射的地址,失败时返回MAP_FAILED

//addr参数指定映射时候被放置的虚拟地址,如果值为NULL则内核自动分配(推荐)

//length参数指定映射的字节数

//prot参数指定映射方式PROT_NONE(区域无法访问),PROT_READ,PROT_WRITE,PROT_EXEC

//flags是MAP_PRIVATE和MAP_SHARED

//最后两个参数是文件映射才有的,文件描述符和文件偏移映射起点

写时复制

写时复制技术是利用在私有映射的一种更改映射内容的方法。如下图所示,当两个进程将一个私有对象映射到他们虚拟内存的不同区域,但是共享这个对象的同一个物理副本。

当没有进程试图写自己的私有区域的某个页面时,就会一直共享着物理内存中对象的一个单独副本。一旦有一个进程要写共享着的某个页面时候,故障处理程序就会在物理内存中创建这个页面的一个新副本,更新页表条目指向这个新的副本,然后恢复这个页面的可写权限,因此进程可在这个新的页面上执行写操作。

9ab0735351f9aa121ff84113811bb4af.png

#include

#include

#include

#include

#include

#include

//相当于cat的功能,私有文件映射(写时复制技术)

int main(int argc,char *argv[]){

if(argc!=2){

printf("error argc\n");

}

int fd=open(argv[1],O_RDONLY);

if(fd==-1){

printf("open file error\n");

}

struct stat sb;

if(fstat(fd,&sb)==-1){

printf("fstat error\n");

}

char *addr=mmap(NULL,sb.st_size,PROT_READ,MAP_PRIVATE,fd,0);

if(addr==MAP_FAILED){

printf("mmap error\n");

}

if(write(1,addr,sb.st_size)!=sb.st_size){

printf("write error\n");

}

exit(0);

}

参考《csapp》《tlpi》《apue》

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值