跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客GitHub 精选镜像工具UI配色美学隐私政策关于联系
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
C

Linux 进程控制

Linux 进程控制主要涵盖进程创建、退出、等待及程序替换四大模块。通过 fork 系统调用创建子进程,利用写时拷贝优化性能。进程可通过 return、_exit 或 exit 退出,需区分正常与非正常退出码。父进程应使用 wait 或 waitpid 回收子进程资源以避免僵尸进程。exec 系列函数可在不改变 PID 的情况下替换当前进程映像,支持不同参数传递与环境变量配置方式。

战神发布于 2026/3/28更新于 2026/5/3132 浏览
Linux 进程控制

1、进程创建

1.1 fork

通过 fork 系统调用,创建子进程。

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>

int main() {
    int ret = fork();
    printf("hello proc : %d!, ret: %d\n", getpid(), ret);
    sleep(1);
    return 0;
}
  • 创建成功,两个返回值,对父进程返回子进程的 PID,对子进程返回 0。因为父:子 = 1:N,父进程需要区分子进程,而子进程能通过 PPID 找到父进程。所以可以 if,让父子进程执行不同的语句。创建失败,返回 -1。
  • fork() 创建子进程后,父子进程都从 fork() 返回处继续执行。注意:子进程不会执行 fork() 之前的代码。
  • 当父子进程尝试修改数据,会发生写时拷贝 (减少创建子进程的时间,减少内存浪费),重新拷贝一份数据。所以父子进程独立运行。
1.2 fork 的常规用法
  1. 父进程创建子进程后,父子进程各自执行不同的逻辑。
  2. 子进程通过 exec 系列函数完全替换为另一个程序。
1.3 fork 失败的原因
  1. 进程总数超过内核限制。
  2. 用户进程数超过配额。

2、进程退出

2.1 基本概念

进程退出,释放代码和数据,没有释放 PCB 对象。

2.2 进程退出场景
  1. 代码运行完毕,结果正确。
  2. 代码运行完毕,结果不正确。
  3. 代码异常终止 (一般是收到了信号)。
2.3 退出码
  1. 如果是异常终止,退出码无意义 (代码都没执行完)。
  2. 不是异常终止,0 为结果正确,非 0 为结果不正确 (不同的值,表示不同的原因)。

注意:

  • $?,显示最近一个进程退出时的退出码。
  • errno,当系统调用或库函数发生错误时,errno 会被设置为对应的错误码。需包含<errno.h>。
  • strerror(),根据错误码,显示错误信息。
2.4 进程常见退出方式
  1. main 函数的 return 退出码,(其他函数的 return,只表示函数调用完成),表示进程退出。
  2. _exit(退出码)。是系统调用,用于进程退出。
  3. exit(退出码)。是 C 标准库函数 (封装了 exit()),先刷新 I/O 缓冲区等,再进程退出。

3、进程等待

3.1 进程等待的必要性
  • 子进程退出,父进程需要获取子进程退出前的信息 (即子进程 PCB 对象里面的信息,其指向的代码和数据已被释放,可选),并释放子进程的 PCB 对象 (必要),如果父进程没有"回收"子进程,那么子进程被称为"僵尸进程",其 PCB 对象将会一直存在,造成内存泄漏。
  • 父进程通过进程等待的方式"回收"子进程。
3.2 进程等待的方式
3.2.1 wait
// stat_loc 输出型参数,记录子进程的退出状态
pid_t wait(int *stat_loc);
  • 父进程阻塞等待任意一个退出的子进程,若子进程退出,返回子进程的 pid,若调用失败,返回 -1。
3.2.2 waitpid(常用)
// pid,指定等待子进程,stat_loc,子进程的退出信息,options,功能
pid_t waitpid(pid_t pid, int *stat_loc, int options);
  • pid,等待指定 pid 的子进程。若为 -1,等待任意一个退出的子进程。
  • stat_loc,输出型参数,32 位,高 16 位不用。
  1. 正常退出,次第八位为进程退出码,低八位为 0。
  2. 异常终止 (一般是收到了信号),次第八位,无意义 (因为代码都没执行完),低八位,core dump(一位)+信号编号 (七位)。
  3. 宏 WEXITSTATUS(stat_loc),获取退出码。
  4. 宏 WIFEXITED(stat_loc),子进程正常退出,为真,否则,为假。
  • options:
  1. 为 0,父进程阻塞等待 (一直等,直到子进程退出),若子进程退出,返回子进程 pid,若调用失败 (如 pid 不存在),返回 -1。
  2. 为 WNOHANG,父进程非阻塞等待 (询问一次,知道子进程的状态,父进程可以做自己的事,一般需要多次询问),若子进程退出,返回子进程 pid,若子进程没有退出,返回 0,若调用失败 (如 pid 不存在),返回 -1。

4、进程程序替换

4.1 替换原理
  • 用 fork 创建子进程后,子进程可以调用一种 exec 系列函数以执行另一个程序。
  • exec 系列函数会替换当前进程的代码段、数据段和堆栈等,但文件描述符表会被保留(引用计数不变)(除非文件描述符设置了 FD_CLOEXEC 标志)。
  • 调用 exec 不会创建新进程,因此调用前后该进程的 PID 保持不变。
4.2 替换函数
  • path/file,是要执行谁,arg/argv,是怎么执行 (命令行怎么写,就怎么写),envp,设置新的环境变量 (会覆盖原有的环境变量)
int execl(const char *path, const char *arg0, ..., NULL);
int execlp(const char *file, const char *arg0, ..., NULL);
int execle(const char *path, const char *arg0, ..., NULL, char *const envp[]);
int execv(const char *path, char *const argv[]);
int execvp(const char *file, char *const argv[]);
int execvpe(const char *file, char *const argv[], char *const envp[]);
函数名参数传递方式是否按照 PATH(环境变量) 搜索是否指定环境变量后缀含义
execl字符串列表❌ 否❌ 默认环境l=list
execv字符串数组❌ 否❌ 默认环境v=vector
execlp字符串列表✅ 是❌ 默认环境p=PATH
execvp字符串数组✅ 是❌ 默认环境p=PATH
execle字符串列表❌ 否✅ 自定义环境e=environment
execvpe字符串数组✅ 是✅ 自定义环境pe=PATH+environment

注意:

  • exec 系列函数,调用失败返回 -1,调用成功就直接替换成新的程序了,无需返回值。所以不用进行返回值判断,因为执行 exec 后面的代码,一定是失败了。
  • 无论是字符串列表还是字符串数组,都要显示以 NULL 结尾。
  • 带了 p,就默认在 PATH 的环境变量下搜索命令。不带 p,要提供绝对路径或相对路径。
  • 带了 e,就设置新的环境变量 (会覆盖原有的环境变量)。
  • 如果新增环境变量,不想覆盖原有的环境变量,子进程直接 putenv(),使用非 e 后缀函数,替换的程序默认使用子进程的环境变量。如果使用带 e 后缀函数,就传 environ(指向当前进程的环境变量表的指针,需声明 extern char ** environ;),替换的程序继承子进程的环境变量。
  • 还有 execve,是系统调用。上面的函数,是对 execve 的封装,以满足不同的场景。
int execve(const char *path, char *const argv[], char *const envp[]);

目录

  1. 1、进程创建
  2. 1.1 fork
  3. 1.2 fork 的常规用法
  4. 1.3 fork 失败的原因
  5. 2、进程退出
  6. 2.1 基本概念
  7. 2.2 进程退出场景
  8. 2.3 退出码
  9. 2.4 进程常见退出方式
  10. 3、进程等待
  11. 3.1 进程等待的必要性
  12. 3.2 进程等待的方式
  13. 3.2.1 wait
  14. 3.2.2 waitpid(常用)
  15. 4、进程程序替换
  16. 4.1 替换原理
  17. 4.2 替换函数
  • 💰 8折买阿里云服务器限时8折了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 🤖 一键搭建Deepseek满血版了解详情
  • 一键打造专属AI 智能体了解详情
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • Agent AI 技术原理拆解与工程实践
  • 大数据思维怎么用?7 个经典案例解析
  • WebDriverAgent 技术深度解析
  • 基于 YOLOv8/v11 与 LLM 的 Web 目标检测及人脸表情识别系统
  • 大模型发展:超越GPT-4与寻求场景平衡应用
  • Flutter 三方库 groq_sdk 的鸿蒙化适配指南
  • Oracle 限制单个用户的并发连接数
  • Discord 机器人创建流程
  • 前端消息提示组件的设计方案与最佳实践
  • LLaMA-Factory 本地环境搭建与安装指南
  • 利用闲置 Mac Mini 部署 OpenClaw 构建本地金融 AI 助手
  • Windows 本地一键部署 OpenClaw 并对接飞书 AI 机器人
  • Vheer:免费免登录的 AI 绘画与视频生成工具
  • AIOps 实践:使用 Dify+LangBot 搭建飞书智能体机器人
  • Arduino BLDC 机器人 IMU 角度读取与 PID 互补滤波控制
  • 主流音视频传输协议(DP、HDMI、USB4 等)性能对比
  • Clawdbot(Moltbot) 飞书机器人配置教程
  • UG/NX 二次开发环境配置:C++ 与 Visual Studio 2019
  • Git 分支管理实战:从基础概念到团队协作规范
  • Ubuntu 20.04 安装 Ollama 及 Open WebUI 部署大型语言模型教程

相关免费在线工具

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

  • Markdown转HTML

    将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online

  • HTML转Markdown

    将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online

  • JSON 压缩

    通过删除不必要的空白来缩小和压缩JSON。 在线工具,JSON 压缩在线工具,online

  • JSON美化和格式化

    将JSON字符串修饰为友好的可读格式。 在线工具,JSON美化和格式化在线工具,online