让你快速掌握 exec 函数族的用法
2023-09-06 15:44:12
1. 进程替换的概念
当我们使用 fork() 系统调用之后,创建出来的子进程是对父进程的复制,也就是说子进程和父进程执行的是相同的程序,虽然说父子进程可能执行的是不同的代码分支(if else 语句)。
但是,在某些情况下,我们需要让子进程执行一个与父进程不同的程序。这时,我们就需要用到 exec 函数族了。
2. exec 函数族的简介
exec 函数族是 Linux 系统中的一组函数,用于替换当前进程的映像。当一个进程调用 exec 函数族中的某个函数时,内核会将该进程的地址空间替换为新程序的地址空间,并将控制权交给新程序。
exec 函数族中包含以下几个函数:
- fork():创建一个子进程,该子进程是父进程的副本。
- execve():用新程序替换当前进程的映像。
- execvp():与 execve() 函数类似,但它会搜索 PATH 环境变量来查找要执行的程序。
- execvpe():与 execvp() 函数类似,但它还允许您指定要使用的环境变量。
3. exec 函数族的详细介绍
3.1 fork() 函数
fork() 函数创建一个子进程,该子进程是父进程的副本。子进程拥有与父进程相同的内存空间、文件符和环境变量。
fork() 函数的原型如下:
pid_t fork(void);
如果 fork() 函数成功,它将返回子进程的进程 ID。如果 fork() 函数失败,它将返回 -1。
3.2 execve() 函数
execve() 函数用新程序替换当前进程的映像。新程序的映像由三个参数指定:
- 程序的路径
- 程序的参数
- 程序的环境变量
execve() 函数的原型如下:
int execve(const char *path, char *const argv[], char *const envp[]);
其中:
- path 是要执行的程序的路径。
- argv 是一个字符串数组,包含要传递给程序的参数。
- envp 是一个字符串数组,包含要传递给程序的环境变量。
如果 execve() 函数成功,它将不会返回。如果 execve() 函数失败,它将返回 -1。
3.3 execvp() 函数
execvp() 函数与 execve() 函数类似,但它会搜索 PATH 环境变量来查找要执行的程序。
execvp() 函数的原型如下:
int execvp(const char *file, char *const argv[]);
其中:
- file 是要执行的程序的文件名。
- argv 是一个字符串数组,包含要传递给程序的参数。
如果 execvp() 函数成功,它将不会返回。如果 execvp() 函数失败,它将返回 -1。
3.4 execvpe() 函数
execvpe() 函数与 execvp() 函数类似,但它还允许您指定要使用的环境变量。
execvpe() 函数的原型如下:
int execvpe(const char *file, char *const argv[], char *const envp[]);
其中:
- file 是要执行的程序的文件名。
- argv 是一个字符串数组,包含要传递给程序的参数。
- envp 是一个字符串数组,包含要传递给程序的环境变量。
如果 execvpe() 函数成功,它将不会返回。如果 execvpe() 函数失败,它将返回 -1。
4. exec 函数族的应用示例
以下是一些 exec 函数族的应用示例:
- 使用 fork() 函数创建一个子进程,然后使用 execve() 函数让子进程执行一个新的程序。
- 使用 execvp() 函数执行一个新的程序,并搜索 PATH 环境变量来查找该程序。
- 使用 execvpe() 函数执行一个新的程序,并指定要使用的环境变量。
5. 总结
exec 函数族是 Linux 系统中的一组非常有用的函数,用于替换当前进程的映像。通过使用 exec 函数族,我们可以轻松地创建新的进程并执行新的程序。