一、核心概述
作用 :fork 创建子进程后,子进程默认与父进程代码一致,通过 exec 函数可以覆盖当前进程程序,执行全新的可执行文件。
核心特性
-
进程 PID 不变,仅替换代码段、数据段;继承已打开的文件描述符
-
成功无返回,exec 后续代码永不执行
-
失败返回 -1,继续执行后续代码
-
标准流程:fork() 创建子进程 → 子进程调用 exec → 父进程 wait() 回收子进程
二、函数后缀含义
-
l(list):逐个罗列参数,可变参数,末尾必须 NULL
-
v(vector):参数存入字符串数组,数组末尾必须 NULL
-
p(PATH):通过系统 PATH 环境变量搜索程序,无需写绝对路径
统一头文件:#include <unistd.h>
三、四大常用函数(声明 + 完整代码示例)
1. execl(绝对路径 + 列表传参)
函数声明
cs
int execl(const char *pathname, const char *arg, ..., (char *)NULL);
代码示例
cs
#include <unistd.h>
#include <stdio.h>
#include <sys/wait.h>
int main()
{
pid_t pid = fork();
if (pid == 0)
{
execl("/bin/ls", "ls", "-l", NULL);
perror("execl fail");
_exit(-1);
}
wait(NULL);
return 0;
}
2. execv(绝对路径 + 数组传参)
函数声明
cs
int execv(const char *pathname, char *const argv[]);
3. execlp(PATH搜索 + 列表传参)
函数声明
cs
int execlp(const char *file, const char *arg, ..., (char *)NULL);
代码示例
cs
#include <unistd.h>
#include <stdio.h>
#include <sys/wait.h>
int main()
{
pid_t pid = fork();
if (pid == 0)
{
execlp("ls", "ls", "-l", NULL);
perror("execlp fail");
_exit(-1);
}
wait(NULL);
return 0;
}
4. execvp(PATH搜索 + 数组传参)
函数声明
cs
int execvp(const char *file, char *const argv[]);
代码示例
cs
#include <unistd.h>
#include <stdio.h>
#include <sys/wait.h>
int main()
{
pid_t pid = fork();
if (pid == 0)
{
char *argv[] = {"ls", "-l", NULL};
execvp("ls", argv);
perror("execvp fail");
_exit(-1);
}
wait(NULL);
return 0;
}
四、函数对比速查表
| 函数名 | 传参方式 | 是否需要绝对路径 |
|---|---|---|
| execl | 列表逐个传参 | 需要 |
| execv | 字符串数组传参 | 需要 |
| execlp | 列表逐个传参 | 不需要(依赖PATH) |
| execvp | 字符串数组传参 | 不需要(依赖PATH) |
五、必考易错点
-
参数列表 / 字符串数组 末尾必须以 NULL 结尾,缺一报错
-
带 p 后缀函数,自定义程序需将所在目录添加到 PATH 环境变量
-
exec 执行失败后,必须用
_exit(-1)退出子进程,防止乱走父进程逻辑 -
exec 只替换程序,不创建新进程,PID 始终不变