写点什么

C++ 中的 exec() 函数

作者:向阳逐梦
  • 2023-06-30
    四川
  • 本文字数:1613 字

    阅读完需:约 5 分钟

C++中的exec()函数

exec()函数在 C++中是一个进程控制函数,用于创建新进程执行其他程序或命令行指令。exec()函数可以替换当前进程的代码和数据,创建新的进程运行其他程序。exec()函数有多个版本,例如 execl、execv、execle、execve 等,根据不同的参数类型和个数来使用。

前言

fork 函数之后,如果想要把子进程换成一个我想要执行的进程,这时,就不得不使用 exec()函数了,这也是 fork()的意义所在。当然,exec系列的函数也可以将当前进程替换掉,不一定非要fork()一个子进程。常见的fork()调用例子有很多,比如从 wechat发起一个语音电话、从 bash或者zsh执行一个 a.out 程序,都是在利用exec系统调用将新产生的子进程完全替换成目标进程。

比如,这是一个死循环程序(目的是为了观察,让它活得久一点):

#include <stdio.h>int main() {    int a = 0;    while (1) {        a++;    }    return 0;}
复制代码

通过编译,执行:

    gcc fork_example.c -o fork_example
./fork_example
复制代码

查看进程:top

可以发现,fork_example 的进程的 PPID 为 54861,我们看看它是谁:ps 54861

  PID   TT  STAT      TIME COMMAND54861 s018  Ss     0:00.23 /bin/zsh -il
复制代码

很明显,它是 zsh,现在可以终止 fork_example:kill 57892

zsh: terminated ./fork_example
复制代码

程序就会结束!以上例子,可以看到我们的子进程,就是由一个父进程fork()之后替换的。

exec()

#include<unistd.h>
复制代码

原型:

int execl(const char *path, const char *arg, ...)int execv(const char *path, char *const argv[])int execle(const char *path, const char *arg, ..., char *const envp[])int execve(const char *path, char *const argv[], char *const envp[])int execlp(const char *file, const char *arg, ...)int execvp(const char *file, char *const argv[])
复制代码

参数:

path参数表示你要启动程序的名称,包括路径名;

arg参数表示启动程序所带的参数,一般第一个参数为要执行命令名

返回值:成功返回 0,失败返回-1

上述 exec 系列函数底层都是通过 execve 系统调用实现:

#include <unistd.h>int execve(const char *filename, char *const argv[],char *const envp[]);#include <unistd.h>int execve(const char *filename, char *const argv[],char *const envp[]);
复制代码

① 查找方式:上表其中前 4 个函数的查找方式都是完整的文件目录路径,而最后 2 个函数(也就是以 p 结尾的两个函数)可以只给出文件名,系统就会自动从环境变量“$PATH”所指出的路径中进行查找。

② 参数传递方式:exec函数族的参数传递有两种方式,一种是逐个列举的方式,而另一种则是将所有参数整体构造成指针数组进行传递。

在这里参数传递方式是以函数名的第 5 位字母来区分的,字母为“l”(list)的表示逐个列举的方式,字母为“v”(vertor)的表示将所有参数整体构造成指针数组传递,然后将该数组的首地址当做参数传给它,数组中的最后一个指针要求是 NULL。读者可以观察 execl、execle、execlp 的语法与 execv、execve、execvp 的区别。

③ 环境变量:exec 函数族使用了系统默认的环境变量,也可以传入指定的环境变量。这里以“e”(environment)结尾的两个函数execle、execve就可以在envp[]中指定当前进程所使用的环境变量替换掉该进程继承的所以环境变量,这极大地提供了灵活度。

execl()

该函数的定义为:

int execl(const char *path, const char *arg, ...)
复制代码

可以看到,它的参数为一个 path,由于不带 p,因此,最后一个参数为 NULL

例如:

#include <stdio.h>#include <unistd.h>int main() {    printf("hello!\n");    // 替换 main 进程    execl("/bin/ls", "ls", "-a", NULL);    // good bye! 并不会被打印出来    printf("good bye!\n");    return 0;}
复制代码

执行结果:

hello!.               a.out           execlp.c        fork_example    myshell.c..              execl.c         fork.c          fork_example.c
复制代码

可以看到,它成功地执行了"ls -a"命令。


发布于: 刚刚阅读数: 4
用户头像

向阳逐梦

关注

人生享受编程,编程造就人生! 2022-06-01 加入

某公司芯片测试工程师,嵌入式开发工程师,InfoQ签约作者,阿里云星级博主,华为云·云享专家。座右铭:向着太阳,追逐梦想!

评论

发布
暂无评论
C++中的exec()函数_向阳逐梦_InfoQ写作社区