32 linux 中物理页的 cow

news2024/10/7 7:28:09

前言

熟悉 linux 进程机制的人都知道 linux 中新建进程是以 fork + exec 的形式创建的进程 

fork 的时候复制了父进程的相关数据结构, 然后更新了待执行的 binary, 去执行  

然后 父子进程之间 内存管理是 基于 copy on write 的 

对于某块物理页, fork 之后内存设置为 只读, 然后 当出现写的请求的时候 复制该物理页, 然后 进行操作 

测试用例

用例主要是 申请了一块空间, 然后设置为 aaa 

然后 fork 了一下, 单个进程 变成了 父子进程, 然后 父进程将 空间设置为 bbbb, 子进程将 空间设置为 ccccc 

这里 就是调试 我们上面的 cow 的流程 

#include "stdio.h"
#include "stdlib.h"
#include "unistd.h"

void processHandler(int pid, char *p1, char *processName) {
    printf(" %s - %d, p1 : 0x%x, %s \n", processName, pid, p1, p1);
}

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

    char *p1 = (char *) malloc(20);
    memset(p1, 'a', 16);
    printf(" %s - %d, p1 : 0x%x, %s \n", "parent", getpid(), p1, p1);

    int childPid = fork();
    sleep(rand() % 5);
    if (childPid == 0) {
        memset(p1, 'b', 16);
        processHandler(getpid(), p1, "child1");
    } else {
        memset(p1, 'c', 16);
        processHandler(getpid(), p1, "parent");
    }

}

cow 父进程 和 子进程 页表项设置为只读

首先禁用掉 ASLR, 在这种 比较小的 case, malloc 调用 brk 申请第一个块空间, 首地址会是 0x602000 

将父进程 和 子进程的页表项设置为只读的地方在这里 

在 copy_pte_range 中可以看到这个 vma 的区间, [6299648 - 6434816] 即为 [0x602000 - 0x6230000] 我们 malloc 申请的这部分的空间 属于这个 vma 

当 父进程 / 子进程 修改了对应的页的内容, cow 复制物理页

按照我们这里的目前的规则, 一次执行会生成两个进程, 不会产生其他的进程 

父进程为 奇数, 子进程为 偶数 

这里便是 父/子 进程尝试修改 [0x602000 - 0x6230000] 所在的空间, 然后 kernel 的相关处理 

先修改的进程 复制原来的物理页, 并设置为 可读写, 然后 对应的进程 再去操作给定的物理页 

后修改的进程 发现可以只有当前进程使用该物理页, 直接复用该物理页 

物理页的复制是基于 kmap_atomic + memcpy 来实现的 

这里的 先操作的进程号是 313, 对应的是 父进程 

后修改的进程 发现可以只有当前进程使用该物理页, 直接复用该物理页 

(initramfs) ./Test23MemoryCowChildFirst 
 parent - 313, p1 : 0x602010, aaaaaaaaaaaaaaaa 
 child1 - 314, p1 : 0x602010, bbbbbbbbbbbbbbbb 
 parent - 313, p1 : 0x602010, cccccccccccccccc 

这里 先操作的是子进程 先修改对应的只读页 的时候 

(initramfs) ./Test23MemoryCowChildFirst 
 parent - 319, p1 : 0x602010, aaaaaaaaaaaaaaaa 
 child1 - 320, p1 : 0x602010, bbbbbbbbbbbbbbbb 
 parent - 319, p1 : 0x602010, cccccccccccccccc 

参考

详细讲解Linux内核写时复制技术COW机制(手撕源代码)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/705963.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

JAVA3

文章目录 注释核心机制JVM的功能 优缺点优点缺点 注释 例子: 核心机制 JVM的功能 优缺点 优点 缺点

FreeRTOS入门(二)

目录 什么是RTOS? 嵌入式有哪些常见的RTOS? ✓ VxWorks(开源收费) ✓ UCOSII&III(开源免费) ✓ FreeRTOS(开源免费) ✓ RT_Thread(开源免费) ✓ AliOS(开源收费) ✓ LiteOS FreeR…

微信小程序canvas层级太高,与其他非原生组件层级冲突

官网已经提出新版本以支持同层渲染,但是实际项目中层级还是冲突的。 最后在文档中找到这样一段话,用真机打开,层级就正常了 。所以建议大家,多使用真机调试去测试!!!!

redis中常用的命令

1.关于对key操作的命令 keys *: 查看redis中所有的key exists key: 判断指定的key是否存在。存在返回1 否则返回0 del key: 删除指定的key expire key seconds: 为指定的key设置过期时间 2.关于库的命令 默认redis中存在16个库 select n: 选中库 n0~15 flushdb: 清空…

C++中的exec()函数

exec()函数在C中是一个进程控制函数,用于创建新进程执行其他程序或命令行指令。exec()函数可以替换当前进程的代码和数据,创建新的进程运行其他程序。exec()函数有多个版本,例如execl、execv、execle、execve等,根据不同的参数类型…

SAP 区分工单BOM物料是手工删除 还是 Teco后自动关闭需求

SAP 区分工单BOM物料是手工删除 还是 Teco后自动关闭需求 首先 resb表删除标识XLOEK 都为 ‘X’,无法通过其它字段直接区分 1先从前台界面区分 手工删除的,组件界面颜色正常,状态为-REL 删除 Teco自动关闭需求的,颜色不一样&am…

python中调用java函数

python中调用java函数 1. 将java项目打包成jar(IDEA)2. 在python中调用jar 1. 将java项目打包成jar(IDEA) 【CtrlShiftAltS】或者“File --> Project Structure --> Project Settings” 选择Artifacts选项卡,点…

[Android Studio]1.2计数器

所有要改的代码如下: MainActivity代码: package com.example.code02;import androidx.appcompat.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.TextView; imp…

FPGA第一个程序入门

1、使用正点原子的达芬奇开发板进行第一个FPGA程序设计。 2、启动vivado 2019.2。 3、 新建工程。 File--Project--New,选择RTL Project(寄存器传输级)。 4、选择器件。 add sources点击next, add constraints点击next&#x…

npm install安装依赖总结

node下载地址:https://nodejs.org/en/download/releases 。可以看到node版本、npm版本、node_module版本 1.npm的全局安装路径 查看默认值: npm get prefix 默认是C:\Users\你的用户名\AppData\Roaming\npm 、 可以通过 npm config prefix 更改全局…

mysql-数据迁移 及报错解决(ERROR 1290 (HY000)

文章目录 1. 物理迁移1. 迁移前,配置mysql的输出目录1. 查看mysql的输出目录2. 修改mysql的输出目录 2. 文件迁移 1. 物理迁移 1. 迁移前,配置mysql的输出目录 1. 查看mysql的输出目录 在安装MySQL的会限制了导入与导出的目录权限。只允许在规定的目录…

量子 能源,节能减排还是另有“端倪”?

光子盒研究院 前言:如今,量子技术早已走出实验室、广泛赋能电力、化学、医学等各个领域;创新赛道上,加速奔跑的量子产业,将带来无限可能。现在,光子盒特开启「量子」专栏,解读量子技术将为下游应…

基于matlab从3D医学图像中对脑肿瘤进行语义分割(附源码)

一、前言 此示例演示如何从 3D 医学图像中对脑肿瘤进行语义分割。 语义分割涉及用类标记 3-D 体积的图像或体素中的每个像素。此示例说明了如何使用 3-D U-Net 深度学习网络在磁共振成像 (MRI) 扫描中对脑肿瘤进行二进制语义分割。U-Net是一个快速&…

【MySQL学习笔记】(五) 表的约束

表的约束 1 什么是约束?2 空属性3 默认值4 列描述5 zerofill6 主键7 自增长8 唯一键9 外键 1 什么是约束? 约束是一种限制,它通过对表的行或列的数据做出限制,来确保数据的完整性、一致性。 真正约束字段的是数据类型&#xff0…

Electron快速入门

目录 前言 一、安装需知 二、安装electron 三、开始 3.1 修改package.json文件 3.2 创建main.js文件 3.3 启动预览窗口 3.4 显示内容 四、 热加载 五、主进程和渲染进程概念介绍 六、自定义原生菜单 6.1 自定义菜单 6.2 给菜单添加点击事件 6.3 抽离菜单定义 6.…

基于SpringBoot+vue的社区维修平台设计与实现

博主介绍: 大家好,我是一名在Java圈混迹十余年的程序员,精通Java编程语言,同时也熟练掌握微信小程序、Python和Android等技术,能够为大家提供全方位的技术支持和交流。 我擅长在JavaWeb、SSH、SSM、SpringBoot等框架…

信号链噪声分析19

文章目录 概要整体架构流程技术名词解释技术细节小结 概要 提示:这里可以添加技术概要 用于定量表示 ADC 动态性能的常用指标有六个,分别是:SINAD(信纳比)、ENOB (有效位数)、SNR(信…

keil_arm 大端小端 寄存器 栈

.text .global _start _start: /* 单寄存器ldr r0,0x40000800ldr r1,0x12345678将r1寄存器中的值,写到r0指向的地址空间中[0x40000800]0x12345678str r1,[r0]将r0指向地址空间中的内容,读到目标寄存器r2中,r20x12345678 ldr r2,[r0] */ /*ldr…

前端设计模式学习

UML类图 1.工厂模式 设计原则:最重要的就是开放封闭原则,对扩展开放,对修改封闭。 1.工厂和类分离,解耦 2.可以扩展多个类 3.工厂的创建逻辑也可以自由扩展 工厂模式可以拆分成三个,分别是工厂方法模式、抽象工厂…

C/C++图形库EasyX保姆级使用教程(二) 图形化窗口设置以及简单图形的绘制

C/C图形库EasyX保姆级使用教程 第一章 Microsoft Visual Studio 2022和EasyX的下载及安装使用 第二章 图形化窗口设置以及简单图形的绘制 文章目录 C/C图形库EasyX保姆级使用教程前言一、窗口!1.如何生成一个图形化窗口?1.头文件2.初始化一个图形化窗口…