首页 > 解决方案 > 为什么 execve 函数映射私有区域?

问题描述

execve我正在阅读一本将 e函数描述为的教科书:

假设当前进程中运行的程序进行如下调用:

execve("a.out", NULL, NULL);

execve 函数在当前进程中加载​​并运行包含在可执行目标文件 a.out 中的程序,有效地将当前程序替换为 a.out 程序。加载和运行 a.out 需要以下步骤

  1. 删除现有用户区
  2. 映射私人区域。为新程序的代码、数据、bss 和堆栈区域创建新的区域结构。所有这些新区域都是私有的写时复制

在此处输入图像描述

  1. 映射共享区域
  2. 设置程序计数器

我对第 2 步有点困惑,所以假设fork()fork 一个子进程并让子进程运行execve一个新程序,那么为什么execve将子进程的新区域映射为私有写时复制?父进程不会与子进程共享内存,因为父子进程映射到不同的对象,为什么子进程害怕其他进程可能会写东西来影响它?

标签: clinuxvirtual-memory

解决方案


如果您查看图表,大多数“写时私有复制”页面都是“零需求”页面。这就是 Linux 处理分配请求的方式;它写时复制映射零页。因此,如果您只是阅读该页面,您会看到它充满了零,但此时它并不占用实际内存。只要您需要写入它,它就会无缝地创建一个新的“真实”页面,其中填充零并将您的写入应用到它。

对于其余部分,就像该.data部分一样,它映射来自可执行文件的原始数据,但您不想修改磁盘上的文件,因为您重新分配了一个全局变量,所以再次使用写时复制。

基本上,它不是从原始程序“复制”一个真实页面,它只是一种从操作系统为程序提供一致归零的页面的策略,并以一种允许在需要时进行修改的方式廉价地提供对原始可执行文件数据的访问。


推荐阅读