Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/spring-mvc/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 使用mremap()将两个相同的页面合并为一个物理页面_C_Linux_Mmap - Fatal编程技术网

C 使用mremap()将两个相同的页面合并为一个物理页面

C 使用mremap()将两个相同的页面合并为一个物理页面,c,linux,mmap,C,Linux,Mmap,我有一个C代码,我知道void*p1指向的页面内容与void*p2指向的页面内容相同。p1和p2是动态分配的。我的问题是,我可以使用remap()让这两个页面指向同一个物理页面,而不是拥有两个相同的物理页面吗 编辑:我正在尝试更改此进程页表中的虚拟到物理映射,以便p1和p2指向相同的物理地址。我不想让p1和p2虚拟地指向同一个对象。如果您试图使用linux页面方案将多个虚拟内存地址映射到单个物理地址,那么mremap()就不适用于此。mremap用于移动(重新映射)现有区域,如果使用它映射到特定

我有一个C代码,我知道void*p1指向的页面内容与void*p2指向的页面内容相同。p1和p2是动态分配的。我的问题是,我可以使用remap()让这两个页面指向同一个物理页面,而不是拥有两个相同的物理页面吗


编辑:我正在尝试更改此进程页表中的虚拟到物理映射,以便p1和p2指向相同的物理地址。我不想让p1和p2虚拟地指向同一个对象。

如果您试图使用linux页面方案将多个虚拟内存地址映射到单个物理地址,那么mremap()就不适用于此。mremap用于移动(重新映射)现有区域,如果使用它映射到特定的新地址,则任何到该地址的旧映射都将无效(根据手册页)

见强调部分

MREMAP_已修复(自Linux 2.3.31起) 此标志的用途与地图固定标志类似 mmap(2)。如果指定了此标志,则mremap()接受 第五个参数,void*new_address,用于指定页面- 映射必须移动到的对齐地址任何 在新地址指定的地址范围上的上一个映射 并且新的大小未映射。如果指定了MREMAP\U FIXED,则 还必须指定MREMAP_MAYMOVE

如果您只是尝试合并两个相同数据结构的存储,则不需要mremap()将两个“页面”指向同一个相同的页面,您需要将两个不同的数据结构指针指向同一页面并释放冗余页面

如果内容相同,则需要将指向p2地址的任何指针转换为p1地址

即使正确地使用mremap需要您处理自己的指针管理,它也不能神奇地为您做到这一点;如果你没有做到这一点,在重新映射之后,你可能会有悬而未决的指针


PS:我做内核编程已经好几年了,所以在我的下一个声明中我可能是错的或过时了,但是我认为您需要使用内核调用(即内核模块/驱动程序级调用)来获取物理映射,因为mmap()和mremap()是用户地调用,并且在虚拟地址空间中工作。“页面映射”是在内核级别,在用户空间之外完成的。

您实际上是在尝试将两个相同数据结构的存储合并为一个吗?我正在尝试更改页面表中的虚拟到物理映射,以便它们指向相同的内容,因此您认为“两个虚拟地址指向一个物理地址”是的,我还认为它可能需要一些我以前没有做过的内核攻击。不过你似乎很有经验。我可以问一下,你对从哪里开始学习内核编程有什么建议吗?你是怎么开始的?因为这绝对是我们在大学里学不到的:)。谢谢你的回答。这真的很有帮助。第一件事是下载内核源代码(或者从发行版源代码安装)。然后买一本关于Linux内核编程的书。上次我在亚马逊上看到了好几个。我的是旧的,我认为从2.0和2.2系列,但仍然给你需要开始。我能建议尝试的最好方法是一个简单的可加载模块,它可以做一些琐碎的事情,比如一个假的设备驱动程序。我还建议您在VM中完成这项工作。在VMware之前,我每天重启100次。但我也不太好。:)很多事情完全可以从用户的土地上完成。从大学级别的操作系统类(IPC、并发编程、TCP/IP服务器、VM、解释器)的角度来看,有太多不需要内核级访问的内容需要探索。实际上,两个虚拟区域完全有可能映射到同一个备份存储。如果备份存储是匿名的,我们通常称之为“共享内存”。如果它是一个文件,那么就更容易掌握:它类似于两个进程在各自的地址空间中打开同一个文件,除了这里我们位于同一地址空间的不同区域(多个MMAP)。当然,您可以像往常一样通过文件描述符链接它们。请参见
MAP\u SHARED
。不需要更新指针。(也许我错过了什么,你看起来很自信。)