一、核心概述
作用:
fork 创建子进程后,子进程默认与父进程代码一致,通过 exec 函数可以覆盖当前进程程序,执行全新的可执行文件。
核心特性
进程 pid 不变,仅替换代码段、数据段;继承已打开的文件描述符
成功无返回,exec 后续代码永不执行
失败返回 -1,继续执行后续代码
标准流程:fork() 创建子进程 → 子进程调用 exec → 父进程 wait() 回收子进程
二、函数后缀含义
l(list):逐个罗列参数,可变参数,末尾必须 null
v(vector):参数存入字符串数组,数组末尾必须 null
p(path):通过系统 path 环境变量搜索程序,无需写绝对路径
统一头文件:#include <unistd.h>
三、四大常用函数(声明 + 完整代码示例)
1. execl(绝对路径 + 列表传参)
函数声明
int execl(const char *pathname, const char *arg, ..., (char *)null);
代码示例
#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(绝对路径 + 数组传参)
函数声明
int execv(const char *pathname, char *const argv[]);
3. execlp(path搜索 + 列表传参)
函数声明
int execlp(const char *file, const char *arg, ..., (char *)null);
代码示例
#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搜索 + 数组传参)
函数声明
int execvp(const char *file, char *const argv[]);
代码示例
#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 始终不变
六、总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。
发表评论