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

相关推荐
科大饭桶26 分钟前
Linux系统编程Day13 -- 程序地址空间(进阶)
linux·运维·c语言·数据结构·c++
rannn_1111 小时前
【Linux学习|黑马笔记|Day3】root用户、查看权限控制信息、chmod、chown、快捷键、软件安装、systemctl、软连接、日期与时区
linux·笔记·后端·学习
十五年专注C++开发2 小时前
通信中间件 Fast DDS(一) :编译、安装和测试
linux·c++·windows·中间件·cmake·vcpkg
唐青枫2 小时前
玩转 Systemd Unit 文件:进阶技巧与服务覆盖实战
linux
yuxb732 小时前
Ansible 实操笔记:Playbook 与变量管理
linux·运维·笔记
朱小弟cs612 小时前
Orange的运维学习日记--41.Ansible基础入门
linux·运维·学习·ci/cd·自动化·ansible·devops
CIb0la12 小时前
kali linux 2025.2安装WPS并设置无报错的详细步骤
linux·运维·wps
醉方休13 小时前
Node.js 精选:50 款文件处理与开发环境工具库
linux·运维·node.js
代码老y14 小时前
从裸机到云原生:Linux 操作系统实战进阶的“四维跃迁”
linux·运维·云原生
CMCST15 小时前
CentOS 7.9 升级 GLibc 2.34
linux·运维·centos