fork的原理

1. fork 的基本原理

当调用 fork() 时,操作系统会执行以下主要步骤:

  1. 分配新的进程结构:

    • 操作系统会为新进程分配一个新的 task_struct 结构(进程控制块,PCB),它用于存储进程的状态、内存信息、文件描述符等。
  2. 复制进程上下文:

    • 进程地址空间: 操作系统会复制父进程的内存页表,从而子进程获得父进程相同的虚拟地址空间内容。现代操作系统中,通常使用写时复制(Copy-On-Write, COW)技术,避免立即复制物理内存数据,而是将父进程的内存页标记为只读,等到子进程或父进程尝试写入时,才真正复制该页数据。
    • 文件描述符表: 子进程会继承父进程的文件描述符表,但文件描述符的引用计数会增加,以表示它们被多个进程共享。
    • 信号处理 : 子进程继承父进程的信号处理设置(除了一些特殊情况,如 SIGCHLD 信号会被重置为默认处理方式)。
    • 进程 ID: 子进程会获得一个新的进程 ID,与父进程不同,但子进程会继承父进程的进程组 ID 和会话 ID。
  3. 更新进程树关系:

    • 内核会将新创建的子进程加入进程树中,成为父进程的子进程。子进程的 parent 指针指向父进程,父进程的子进程链表会新增该子进程。
  4. 返回值:

    • 对于父进程,fork() 返回子进程的 PID。
    • 对于子进程,fork() 返回 0。

2. fork 的详细步骤

从 Linux 内核源码角度来看,fork() 的实现实际上是通过 do_fork() 完成的,该函数负责创建子进程并复制父进程的各种信息。

具体流程如下:

  1. 调用 do_fork():

    • 用户进程调用 fork() 时,会陷入内核,由内核函数 do_fork() 来处理实际的创建工作。
  2. 复制进程信息:

    • do_fork() 函数会调用 copy_process() 函数,后者负责复制父进程的各种信息。包括创建一个新的 task_struct,复制父进程的内存地址空间(使用 COW),文件描述符表,信号处理表等。
  3. 设置子进程状态:

    • 内核会将新创建的子进程的状态设置为就绪态,等待被调度。
  4. 返回:

    • do_fork() 最后会将子进程的 PID 返回给父进程,并将 0 返回给子进程。

3. 写时复制 (Copy-On-Write, COW)

在内存管理中,COW 技术是 fork() 中一个关键的优化点。父子进程共享同一块物理内存,只是在内存页被写入时才进行实际的物理内存复制。这大大提高了 fork() 的效率,特别是对于不需要立即修改内存的场景,例如 fork 后立即执行 exec,加载新的程序映像。

  • 页表复制 : fork() 时,子进程会继承父进程的页表结构,这样子进程的虚拟内存布局与父进程保持一致。
  • 页表标记: 所有被继承的页表项会被标记为只读。当父或子进程尝试写入内存时,CPU 会触发页错误(page fault),内核在处理页错误时检测到这是 COW 的情况,就会复制该内存页,解除只读限制并重新映射。

4. 进程上下文切换与 fork()

当一个进程调用 fork() 后,子进程进入就绪队列,等待调度程序的调度。当调度程序决定切换到子进程时,子进程会从复制的父进程上下文开始执行。这意味着子进程会从 fork() 的返回点开始执行,只不过它返回的是 0

推荐学习 https://xxetb.xetslk.com/s/p5Ibb

相关推荐
厨 神7 分钟前
vmware中的ubuntu系统扩容分区
linux·运维·ubuntu
Karoku06612 分钟前
【网站架构部署与优化】web服务与http协议
linux·运维·服务器·数据库·http·架构
geek_Chen0114 分钟前
虚拟机共享文件夹开启后mnt/hgfs/下无sharefiles? --已解决
linux·运维·服务器
(⊙o⊙)~哦1 小时前
linux 解压缩
linux·运维·服务器
牧小七2 小时前
Linux命令---查看端口是否被占用
linux
鸡鸭扣3 小时前
虚拟机:3、(待更)WSL2安装Ubuntu系统+实现GPU直通
linux·运维·ubuntu
友友马3 小时前
『 Linux 』HTTP(一)
linux·运维·服务器·网络·c++·tcp/ip·http
记得开心一点嘛4 小时前
在Linux系统上使用Docker部署javaweb项目
linux·运维·docker
Tak1Na5 小时前
2024.9.18
linux·运维·服务器
Yana.nice5 小时前
linux中将文本转为unix格式
linux