二、exec函数族
1. 简介
- 进程程序替换原理
fork创建子进程执行的是和父进程相同的程序(也有可能是某个分支),通常fork出的子进程是为了完成父进程所分配的任务,所以子进程通常会调用一种exec函数(六种中的任何一种)来执行另一个任务。当进程调用exec函数时,当前用户空间的代码和数据会被新程序所替换,该进程就会从新程序的启动历程开始执行。在这个过程中没有创建新进程,所以调用exec并没有改变进程的id。
- 替换图解(图解)
(1). execl函数原型:
int execl(const char *path, const char *arg, ...);
分析:
- path: 要执行的程序的绝对路径
- 变参arg: 要执行的程序的需要的参数
- 第一arg:占位
- 后边的arg: 命令的参数
- 参数写完之后: NULL
- 一般执行自己写的程序
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(void)
{
printf("entering main process---\n");
if(execl("ls","ls","-l",NULL)<0)
perror("excl error");
return 0;
}
输出结果:
(2). execv函数原型:
int execv(const char *path, char *const argv[]);
分析:
- path = /bin/ps
- char* args[] = {"ps", "aux", NULL};
- execv("/bin/ps", args);
(3). execlp函数原型
int execlp(const char *file, const char *arg, ...);
分析:
- file: 执行的命令的名字
- 第一arg:占位
- 后边的arg: 命令的参数
- 参数写完之后: NULL
- 执行系统自带的程序
-
execlp执行自定义的程序: file参数绝对路径
(4). execvp函原型:
int execvp(const char *file, char *const argv[]);
(5). execle函数原型:
int execle(const char *path, const char *arg, ..., char *const envp[]);
分析:
- path: 执行的程序的绝对路径 /home/itcast/a.out
- arg: 执行的的程序的参数
- envp: 用户自己指定的搜索目录, 替代PATH
- char* env[] = {"/home/itcast", "/bin", NULL};
int execve(const char *path, char *const argv[], char *const envp[]);
函数名 | 参数格式 | 是否带路径 | 是否使用当前环境变量 |
---|---|---|---|
execl | 参数列表 | 否 | 是 |
execlp | 参数列表 | 是 | 是 |
execle | 参数列表 | 否 | 是 |
execv | 参数数组 | 否 | 是 |
execvp | 参数数组 | 是 | 是 |
execve | 参数数组 | 否 | 否 |
7. 测试代码
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
int main()
{
for (int i = 0; i < 8; ++i)
printf(" parent i = %d\n", i);
pid_t pid = fork();
if (pid == 0)
{
execlp("ps", "ps", "aux", NULL);
perror("execlp");
exit(1);
}
for (int i = 0; i < 3; ++i)
printf("----------- i = %d\n", i);
return 0;
}