news 2026/6/9 12:36:00

Linux 进程控制:exec 族函数、waitpid、system 及目录操作详解

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Linux 进程控制:exec 族函数、waitpid、system 及目录操作详解

在 Linux 系统编程中,进程创建与控制是核心知识点。本文将详细讲解exec族函数(进程程序替换)、waitpid(子进程回收)、system(Shell 命令执行)以及getcwd/chdir(目录操作),结合内存原理、函数用法和实际案例,帮你彻底掌握这些关键接口。

一、exec 族函数:进程程序替换

1. 核心功能与原理

exec族函数的核心作用是替换当前进程的代码段和数据段,执行系统中另一个可执行文件。

  • 执行后,原进程的代码、数据被新程序完全覆盖(进程 PID、PPID、打开的文件描述符等核心属性不变);
  • 新程序执行结束后,整个进程直接退出(不会回到原程序执行点);
  • 通常与fork搭配使用:父进程fork创建子进程,子进程通过exec替换为目标程序,父进程负责回收子进程资源。

2. 内存视角变化

阶段内存状态
exec 执行前进程内存包含原程序的代码段、数据段、堆栈
exec 执行后原程序代码段、数据段被新程序替换,堆栈重新初始化

3. 4 个常用 exec 函数(重点)

exec族函数命名有规律:l(list 参数)、v(vector 数组参数)、p(PATH 环境变量查找),核心区别如下:

函数原型关键参数说明核心特点
int execl(const char *path, const char *arg, ...);path:新程序路径 + 文件名(如/bin/ls);arg:参数列表(第一个参数通常是程序名,最后必须以NULL结尾)参数逐个列出,直观简单
int execlp(const char *file, const char *arg, ...);file:新程序文件名(如ls);系统自动在PATH环境变量路径中查找程序无需写全路径,依赖环境变量
int execv(const char *path, char *const argv[]);path:新程序路径 + 文件名argv:参数数组(最后一个元素必须是NULL参数存放在数组中,适合参数数量不确定的场景
int execvp(const char *file, char *const argv[]);file:新程序文件名argv:参数数组;自动在PATH中查找无路径 + 数组参数,最灵活常用
注意事项
  • 所有exec函数执行成功后不会返回(代码段已被替换);若返回,则表示执行失败(返回-1)。
  • 若要执行自定义可执行程序,无论哪个exec函数,第一个参数(pathfile)都需写完整路径 + 文件名(如./myprogram),因为自定义程序通常不在PATH中。

4. 代码示例(exec+fork+waitpid)

c

运行

二、waitpid:子进程资源回收

fork创建的子进程若不回收,会变成僵尸进程(占用 PID 资源),waitpid是回收子进程的核心函数(waitwaitpid的简化版,waitpid(-1, status, 0) == wait(status))。

1. 函数原型与参数

c

运行

pid_t waitpid(pid_t pid, int *status, int options);
参数取值与含义
pid--1:回收所有子进程(等同于wait);- 正数:回收指定 PID 的子进程;-0:回收与当前进程同组的子进程;- 负数:回收进程组 ID 为-pid的子进程
status- 非 NULL:存储子进程退出状态(需通过宏解析);- NULL:不关注退出状态
options-0阻塞模式(父进程暂停执行,直到有子进程退出);-WNOHANG非阻塞模式(父进程不等待,立即返回)

2. 返回值说明

返回值含义
正数成功回收的子进程 PID
0options=WNOHANG时,没有子进程退出(需再次尝试回收)
-1错误(如无子进程可回收,errno 会被设置)

3. 状态解析宏(status 非 NULL 时)

通过以下宏解析子进程退出状态:

  • WIFEXITED(status):子进程是否正常退出(返回非 0 为正常);
  • WEXITSTATUS(status):获取正常退出的状态码(仅WIFEXITED为真时有效);
  • WIFSIGNALED(status):子进程是否被信号终止(返回非 0 为是);
  • WTERMSIG(status):获取终止子进程的信号编号。

三、system:执行 Shell 命令

1. 核心功能

system函数封装了fork+exec+waitpid,直接执行一个 Shell 命令(如ls -lmkdir test),无需手动创建子进程和回收。

2. 函数原型与返回值

c

运行

int system(const char *command);
  • command:要执行的 Shell 命令字符串(如"ls -l""rm -rf temp.txt");
  • 返回值:-1表示执行失败(如 fork 失败);其他值为命令执行结果(需结合waitpid状态解析)。

3. 注意事项

  • system执行的命令运行在子 Shell 中,无法修改父进程的状态(如环境变量、工作目录);
  • 适合执行简单的 Shell 命令(如文件操作、信息输出),复杂场景建议用fork+exec
  • 避免在信号处理函数中调用system(可能导致信号阻塞问题)。

4. 代码示例

c

运行

四、目录操作:getcwd 与 chdir

1. getcwd:获取当前工作路径

函数原型

c

运行

char *getcwd(char *buf, size_t size);
  • buf:存储当前路径的字符数组;
  • sizebuf的最大长度(需足够容纳路径,包括末尾的\0);
  • 返回值:成功返回buf指针,失败返回NULL(如buf长度不足)。
示例

c

运行

#include <stdio.h> #include <unistd.h> #include <stdlib.h> int main() { char buf[1024]; // 定义足够大的缓冲区 if (getcwd(buf, sizeof(buf)) == NULL) { perror("getcwd failed"); exit(1); } printf("当前工作路径:%s\n", buf); return 0; }

2. chdir:改变当前工作路径

函数原型

c

运行

int chdir(const char *path);
  • path:目标路径(绝对路径如/home/user,相对路径如../test);
  • 返回值:成功返回0,失败返回-1(如路径不存在)。
示例(结合 getcwd)

c

运行

#include <stdio.h> #include <unistd.h> #include <stdlib.h> int main() { char buf[1024]; // 获取初始路径 getcwd(buf, sizeof(buf)); printf("初始路径:%s\n", buf); // 切换到/home目录(需根据实际系统调整路径) if (chdir("/home") == -1) { perror("chdir failed"); exit(1); } // 获取切换后路径 getcwd(buf, sizeof(buf)); printf("切换后路径:%s\n", buf); return 0; }

五、关键总结

  1. exec 族:替换进程程序,与fork搭配使用,执行成功不返回;
  2. waitpid:回收子进程,支持阻塞 / 非阻塞模式,避免僵尸进程;
  3. system:简化 Shell 命令执行,内部封装fork+exec+waitpid,无法修改父进程状态;
  4. getcwd/chdir:获取 / 切换工作路径,chdir仅影响当前进程(子进程不继承)。
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/9 15:17:52

LangChain实战快速入门笔记(三)--LangChain使用之Memory

LangChain实战快速入门笔记&#xff08;三&#xff09;–LangChain使用之Memory 文章目录LangChain实战快速入门笔记&#xff08;三&#xff09;--LangChain使用之Memory一、Memory概述1. &#x1f916;&#xff1a;为什么需要Memory&#xff1f;2. &#x1f916;&#xff1a;什…

作者头像 李华
网站建设 2026/6/9 15:18:22

【Java毕设项目】基于微信小程序的仓储管理系统+SpringBoot后端实现

【Java毕设项目】基于微信小程序的仓储管理系统SpringBoot后端实现 weixin185-基于微信小程序的仓储管理系统SpringBoot后端实现 文章目录【Java毕设项目】基于微信小程序的仓储管理系统SpringBoot后端实现一、内容包括二、运行环境三、需求分析四、功能模块五、效果图展示【部…

作者头像 李华
网站建设 2026/6/8 22:12:58

LobeChat能否实现负载均衡?高可用架构设计建议

LobeChat 能否实现负载均衡&#xff1f;高可用架构设计建议 在企业级 AI 应用日益普及的今天&#xff0c;一个稳定、可扩展的前端交互界面往往决定了用户体验的成败。LobeChat 作为一款现代化、开源的聊天机器人 Web 界面&#xff0c;凭借其优雅的设计和强大的多模型接入能力&a…

作者头像 李华
网站建设 2026/6/8 21:24:00

Locust:可能是一款最被低估的压测工具

01 Locust介绍 开源性能测试工具https://www.locust.io/&#xff0c;基于Python的性能压测工具&#xff0c;使用Python代码来定义用户行为&#xff0c;模拟百万计的并发用户访问。每个测试用户的行为由您定义&#xff0c;并且通过Web UI实时监控聚集过程。 压力发生器作为性能…

作者头像 李华
网站建设 2026/6/9 4:00:40

大模型完全指南:小白入门到程序员精通,一篇就够,必收藏

本文系统介绍了大模型、大语言模型、端到端模型和多模态大模型的概念、工作原理及应用案例。文章详细阐述了大模型训练的基础要素&#xff08;数据、算法、算力&#xff09;和训练流程&#xff0c;解释了各类模型的特点和区别&#xff0c;特别强调了多模态大模型处理和理解不同…

作者头像 李华
网站建设 2026/6/8 9:17:22

【收藏必备】小白也能懂的大模型全解析:原理、应用与实战

这篇文章全面介绍了大模型技术&#xff0c;包括定义、特点&#xff08;海量参数、训练数据和计算能力&#xff09;、技术原理&#xff08;Transformer架构、预训练与微调、分布式训练等&#xff09;、应用场景&#xff08;NLP、计算机视觉、多模态&#xff09;及面临的挑战&…

作者头像 李华