c - 为什么 execve 函数映射私有区域?
问题描述
execve
我正在阅读一本将 e函数描述为的教科书:
假设当前进程中运行的程序进行如下调用:
execve("a.out", NULL, NULL);
execve 函数在当前进程中加载并运行包含在可执行目标文件 a.out 中的程序,有效地将当前程序替换为 a.out 程序。加载和运行 a.out 需要以下步骤
- 删除现有用户区
- 映射私人区域。为新程序的代码、数据、bss 和堆栈区域创建新的区域结构。所有这些新区域都是私有的写时复制:
- 映射共享区域
- 设置程序计数器
我对第 2 步有点困惑,所以假设fork()
fork 一个子进程并让子进程运行execve
一个新程序,那么为什么execve
将子进程的新区域映射为私有写时复制?父进程不会与子进程共享内存,因为父子进程映射到不同的对象,为什么子进程害怕其他进程可能会写东西来影响它?
解决方案
如果您查看图表,大多数“写时私有复制”页面都是“零需求”页面。这就是 Linux 处理分配请求的方式;它写时复制映射零页。因此,如果您只是阅读该页面,您会看到它充满了零,但此时它并不占用实际内存。只要您需要写入它,它就会无缝地创建一个新的“真实”页面,其中填充零并将您的写入应用到它。
对于其余部分,就像该.data
部分一样,它映射来自可执行文件的原始数据,但您不想修改磁盘上的文件,因为您重新分配了一个全局变量,所以再次使用写时复制。
基本上,它不是从原始程序“复制”一个真实页面,它只是一种从操作系统为程序提供一致归零的页面的策略,并以一种允许在需要时进行修改的方式廉价地提供对原始可执行文件数据的访问。
推荐阅读
- arrays - 使用数组过滤器更新多个嵌套数组在猫鼬中不起作用
- java - 如何在按钮中居中绘制可绘制对象?
- reactjs - React Web 应用程序中的 Worldpay 3D 安全
- azure - 无法为组注册中的设备生成证书 - 天蓝色
- ios - Firebase 与模拟器连接,但不在真实设备 iOS 中
- python - 从烧瓶中找到实际调用以在端口 5000 上运行
- javascript - 当对象键与当前用户 ID 相同时访问对象的值(角度和火力)
- c# - EF Core:INSERT 语句与 FOREIGN KEY 约束冲突
- css - 如何启用字体变体,如“斜体显示”
- javascript - Cookie 信息弹出制造商 - 在用户拒绝后如何不发送 cookie?