Windows XP Windows 7 Windows 2003 Windows Vista Windows 綜合教學 Linux 系統教學
Windows 10 Windows 8 Windows 2008 Windows NT Windows Server 電腦軟體教學
您现在的位置: Windows教程網 >> Windows教程 >  >> Linux 系統教學 >> 關於 Linux

Linux fork() 系统调用原理与写时复制(COW)机制深度解析

編輯:關於 Linux

fork() 是 Unix/Linux 创建进程的核心系统调用。现代 Linux 通过 clone() 系统调用实现 fork()、vfork() 与 __clone(),并采用写时复制(Copy-on-Write, COW)技术最小化内存复制开销。本文深度解析实现流程与内核关键函数。

一、用户空间调用链

fork()          → glibc wrapper
    → clone(CLONE_CHILD_CLEARTID | CLONE_CHILD_SETTID | SIGCHLD, 0)
        → sys_clone() (内核入口)
            → do_fork()
                → copy_process()

二、copy_process() 核心步骤

  1. 复制 task_struct:dup_task_struct() 分配新内核栈、thread_info、task_struct,内容与父进程相同。
  2. 资源限额检查:当前用户进程数是否超过 RLIMIT_NPROC。
  3. 初始化子进程标识:清零统计计数器、设置 TASK_UNINTERRUPTIBLE 防止抢占、清除 PF_SUPERPRIV、设置 PF_FORKNOEXEC。
  4. 分配 PID:get_pid() 获取新 PID。
  5. 根据 clone flags 共享/复制资源:
    • 文件描述符表(CLONE_FILES)
    • 文件系统信息(CLONE_FS)
    • 信号处理函数(CLONE_SIGHAND)
    • 地址空间(CLONE_VM,fork() 不设置,故复制页表指针,启用 COW)
    • 命名空间(CLONE_NEW*)
  6. 时间片平分:父子进程各得剩余时间片一半。
  7. 返回子进程指针。

三、写时复制(COW)机制

  • fork() 后,父子进程共享物理页面,页表项标记为只读。
  • 任一进程尝试写入共享页 → 触发缺页中断 → 内核复制该页 → 映射为可写 → 进程继续执行。
  • 若 fork() 后立即 exec(),地址空间完全替换,无任何页面实际复制,极大提升效率。

四、do_fork() 返回与调度

  • copy_process() 成功 → wake_up_new_task() 唤醒子进程 → 放入运行队列。
  • 内核有意让子进程先运行:多数子进程紧随 exec(),避免父进程先写入触发不必要的 COW 复制。

五、vfork() 差异

  • vfork() 设置 CLONE_VM | CLONE_VFORK,父子完全共享地址空间,父进程挂起直到子进程 exec() 或 exit()。
  • 子进程不得修改内存(否则破坏父进程),仅用于立即 exec() 场景。

fork clone do_fork copy_process 调用链示意图

理解 fork() → clone() → do_fork() → copy_process() 调用链与 COW 机制,是掌握 Linux 进程管理、容器技术(命名空间隔离)与高性能服务器编程的基石。

Copyright © Windows教程網 All Rights Reserved