news 2026/4/18 0:29:46

Linux 进程创建与终止全解析:fork 原理 + 退出机制实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Linux 进程创建与终止全解析:fork 原理 + 退出机制实战

Linux 进程创建与终止全解析:fork 原理 + 退出机制实战

Linux 中进程创建和终止是操作系统最核心、最基础的行为之一,理解清楚这两个过程,对理解进程管理、资源分配、僵尸进程、孤儿进程、wait/waitpid、信号处理等都至关重要。

本文将从原理到实践,完整梳理 Linux 进程的创建(主要是fork)与终止(_exit/exit/return/ 信号)全流程。

一、进程创建的核心机制:fork / vfork / clone

Linux 中创建新进程最常用的系统调用是fork(),现代实现中还有vfork()clone()(后者是 glibc 和 pthread 的底层)。

1. fork() 是如何工作的?

fork()的核心语义是:“复制当前进程,得到一个几乎完全相同的子进程”

  • 调用一次,返回两次(这是 fork 最经典的描述)
  • 父进程返回子进程的 pid(>0)
  • 子进程返回 0
  • 出错返回 -1

fork 后父子进程的内存布局对比(关键点)

内容父进程子进程说明
代码段 (text)相同相同(共享)现代 Linux 使用写时复制(COW)
数据段 (data/bss)拷贝一份拷贝一份写时复制:父子首次都只读,写时才真正复制页面
拷贝一份拷贝一份同上,写时复制
拷贝一份拷贝一份子进程有独立的栈,但初始内容几乎相同
打开的文件描述符复制(共享同一文件表项)复制父子共享打开文件的偏移量
进程 ID (pid)不变新的(由内核分配)子进程获得新的 PID
父进程 ID (ppid)不变变为调用 fork 的进程 ID子进程的父进程变为 fork 的调用者
信号处理方式复制复制但未决信号集被清空
内存映射(mmap)复制映射描述复制共享映射仍然共享,私有映射写时复制

写时复制(Copy-On-Write, COW)是现代 fork 高效的关键:

  • fork 刚完成时,父子进程的页表指向相同的物理页面(只读)
  • 任何一个进程写内存时,触发页面错误→ 内核复制一份物理页面 → 修改页表指向新页面
  • 这使得 fork 本身非常快(只需要复制页表和少量内核结构)
2. vfork() 与 fork() 的区别

vfork()是 fork 的一个变种,专为“立刻 exec”的场景设计。

特性fork()vfork()
子进程是否复制父进程地址空间是(写时复制)(共享父进程地址空间)
子进程能否修改父进程变量是(写时复制后独立)父进程阻塞,子进程修改会影响父进程
子进程是否能返回父进程继续执行可以不允许(必须 exec 或 _exit)
父进程何时继续执行fork 返回后立即继续等待子进程 exec 或退出
典型使用场景普通创建子进程紧接着 exec 家族函数

vfork 的使用场景(现已较少使用):

if(vfork()==0){// 子进程execl("/bin/ls","ls","-l",NULL);_exit(1);// 一定不能 return}

现代建议:大多数情况下直接用fork()+exec即可,内核已经高度优化。

3. clone() —— pthread 和容器技术的底层

clone()是 Linux 提供的最底层进程创建接口,fork()vfork()都是基于 clone 实现的。

intclone(int(*fn)(void*),void*child_stack,intflags,void*arg,...);

flags最关键,可以控制共享哪些资源:

  • CLONE_VM:共享虚拟内存(线程)
  • CLONE_FILES:共享打开文件表
  • CLONE_FS:共享文件系统信息(根目录、工作目录)
  • CLONE_SIGHAND:共享信号处理方式
  • CLONE_THREAD:创建线程(LWP)
  • CLONE_PARENT_SETTID / CLONE_CHILD_SETTID:设置 tid 地址

Docker / LXC / runc 容器就是大量使用 clone() + 各种 namespace + cgroups 实现的。

二、进程终止的完整机制

Linux 中进程终止的方式有很多,但底层都最终走到do_exit()

1. 用户态常见的退出方式
方式实际调用链是否执行 atexit / on_exit是否刷新 stdio 缓冲区是否调用信号 SIGCHLD
return从 mainexit()
exit(int status)exit() → _exit()
_exit(int status)系统调用 exit_group / exit
_Exit(int status)同 _exit
被信号杀死内核直接 do_exit
2. 进程退出时的核心动作(do_exit)

内核函数do_exit()做以下事情(简化版):

  1. 设置进程状态为TASK_ZOMBIE(僵尸态)
  2. 释放大部分资源(文件描述符、内存映射、信号处理等)
  3. 把退出码保存到 task_struct->exit_code
  4. 通知父进程(发送 SIGCHLD)
  5. 如果父进程不 wait,则进入僵尸状态
  6. 调度器不会再调度该进程,但 task_struct 保留直到父进程 wait
3. 僵尸进程、孤儿进程、wait/waitpid
术语定义如何产生如何消除
僵尸进程已终止但父进程未 wait,task_struct 仍存在子进程 exit,父未 wait父进程 wait / waitpid
孤儿进程父进程先终止,子进程仍在运行父进程先 exitinit(pid=1)或 kthreadd 收养
僵尸+孤儿父进程先 exit,子进程再 exit,但 init 未及时 wait极端情况init 会回收

wait / waitpid 核心区别

pid_twait(int*wstatus);// 等待任意子进程pid_twaitpid(pid_tpid,int*wstatus,intoptions);
  • pid > 0:等待指定 pid 的子进程
  • pid = 0:等待同一进程组的任意子进程
  • pid = -1:等待任意子进程(等价于 wait)
  • pid < -1:等待进程组 |pid| 的任意子进程

常用 options

  • WNOHANG:非阻塞
  • WUNTRACED:报告停止的子进程(SIGSTOP)

三、实战代码示例

1. 普通 fork + wait
#include<stdio.h>#include<unistd.h>#include<sys/wait.h>#include<stdlib.h>intmain(){pid_tpid=fork();if(pid<0){perror("fork");exit(1);}if(pid==0){// 子进程printf("我是子进程,pid=%d, ppid=%d\n",getpid(),getppid());sleep(1);exit(42);}else{// 父进程printf("我是父进程,pid=%d, 子进程pid=%d\n",getpid(),pid);intstatus;pid_twpid=waitpid(pid,&status,0);if(WIFEXITED(status)){printf("子进程正常退出,退出码:%d\n",WEXITSTATUS(status));}elseif(WIFSIGNALED(status)){printf("子进程被信号杀死,信号:%d\n",WTERMSIG(status));}}return0;}
2. 僵尸进程演示
intmain(){pid_tpid=fork();if(pid==0){printf("子进程 pid=%d 退出\n",getpid());exit(0);}// 父进程不 wait,进入死循环while(1)sleep(1);}

运行后ps aux | grep Z即可看到僵尸进程。

四、总结:最核心的几句话

  1. fork是复制进程,现代 Linux 使用写时复制,开销很小。
  2. exec家族函数替换进程映像(加载新程序)。
  3. 进程结束最终调用do_exit,变成僵尸态
  4. 父进程必须wait / waitpid回收子进程,否则产生僵尸进程
  5. 父进程先死,子进程成为孤儿进程,会被 init(pid=1)收养。

如果你想继续深入某个具体方向(例如:多级管道实现、信号在 fork 中的继承与重置、exec 家族完整对比、clone 系统调用的 flags 组合、僵尸进程危害与清理、waitpid 的 options 使用技巧等),可以直接告诉我,我可以继续展开详细代码与讲解。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/18 4:40:08

Wordtune

1. 它是什么Wordtune 是一个基于人工智能的写作辅助工具。它的核心功能是理解用户输入的句子或段落&#xff0c;并提供多种不同的改写方式和表达建议。可以将它想象成一个时刻在线的文字编辑伙伴&#xff0c;专门帮助调整句子的语气、清晰度和流畅性&#xff0c;而不是仅仅纠正…

作者头像 李华
网站建设 2026/4/18 6:30:10

AI写论文的法宝!4款AI论文写作工具,助力高质量论文产出!

四款AI论文写作工具实测推荐 撰写期刊论文、毕业论文或者职称论文的时候&#xff0c;许多学者都会遇到各种各样的难题。对于需要手动撰写的论文&#xff0c;面对成堆的相关文献&#xff0c;无异于在沙滩上寻找珍珠&#xff1b;严格的格式要求常常让人感到无比压力&#xff0c;…

作者头像 李华
网站建设 2026/4/18 7:47:04

AI写论文必备!4款AI论文写作神器,高效完成毕业论文不是梦!

学术论文写作的AI工具实测推荐 在撰写期刊论文、毕业论文或职称论文的过程中&#xff0c;学术研究者经常会遇到不少挑战。面对海量的文献资料&#xff0c;有时查找相关信息就像在大海中捞针&#xff1b;而严格的格式要求常常让写作者感到压力山大&#xff1b;不断的修改过程又…

作者头像 李华
网站建设 2026/4/18 6:26:36

【小程序毕设源码分享】基于springboot+小程序的个性化推荐的外卖点餐系统的设计与实现(程序+文档+代码讲解+一条龙定制)

发布文章 【小程序毕设全套源码文档】基于微信小程序的个性化推荐的外卖点餐系统设计与实现(丰富项目远程调试讲解定制) 56/100 bishe638 未选择任何文件 博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈…

作者头像 李华
网站建设 2026/4/18 8:48:14

‌暗物质探测:图神经网络在粒子对撞异常事件的识别工具‌

当软件测试遇上宇宙探索 在软件测试领域&#xff0c;我们每天都在与异常事件“斗智斗勇”——从代码缺陷到系统崩溃&#xff0c;检测和修复这些问题是核心职责。有趣的是&#xff0c;高能物理学家也在进行类似的“测试”&#xff1a;他们用粒子对撞机模拟宇宙事件&#xff0c;…

作者头像 李华
网站建设 2026/4/18 8:44:08

Java基于web的医疗设备管理系统毕业论文+PPT(附源代码+演示视频)

文章目录一、项目简介1.1 运行视频1.2 &#x1f680; 项目技术栈1.3 ✅ 环境要求说明1.4 包含的文件列表前台运行截图后台运行截图项目部署源码下载一、项目简介 项目基于SpringBoot框架&#xff0c;前后端分离架构&#xff0c;后端为SpringBoot前端Vue。基于Web的医疗设备管理…

作者头像 李华