Linux进程替换

1.替换原理

fork 创建子进程后执行的是和父进程相同的程序 ( 但有可能执行不同的代码分支 ), 子进程往往要调用一种 exec 函数以执行另一个程序。当进程调用一种exec 函数时 , 该进程的用户空间代码和数据完全被新程序替换 , 从新程序的启动例程开始执行。调用exec 并不创建新进程 , 所以调用 exec 前后该进程的 id 并未改变。

2. 替换函数

其实有六种以 exec 开头的函数 , 统称 exec 函数,均包含在头文件<unistd.h>中。

函数解释

1. 这些函数如果调用成功则加载新的程序从启动代码开始执行 , 不再返回。
2. 如果调用出错则返回 -1
3. 所以 exec 函数只有出错的返回值而没有成功的返回值。

命名理解

这些函数原型看起来很容易混 , 但只要掌握了规律就很好记。
l(list) : 表示参数采用列表
v(vector) : 参数用数组
p(path) : p 自动搜索环境变量 PATH
e(env) : 表示自己维护环境变量

execl接口

函数原型如下:

int execl(const char* pathname, const char* arg, ... /* (char  *) NULL */);

其接收两个固定的参数pathname和arg,以及一个可变参数...

pathname:用于指定替换的进程的路径
arg:以何种方式运行进程
...:以何种方式运行该进程
另外的,函数声明中还有一小段备注/* (char *) NULL */,其意图告诉使用者:使用可变参数...时,必须以NULL空指针来结尾。例如:

我们在当前目录下有一个process.c文件

以及test1.c文件来测试execl函数,并将其运行起来看看

可以看到,在execl start之后,发送进程替换,把process.exe替换到当前进程后,输出了五条I am process!,但是最后一句execl over!消失了。

这是因为,进程替换不是简单的执行别的进程的代码,而是用别的进程的代码区覆盖掉自己原先的代码区,所以execl 一旦执行,整个进程的代码都被替换了,那么printf("execl over\n");就会被覆盖掉,最后不输出。

当然我们也可以替换shell中执行的指令,因为这些指令的运行也是进程。例如,

execlp接口

函数原型如下:

int execlp(const char* file, const char* arg, ... /* (char  *) NULL */);
  • file:用于指定替换的进程名称
  • arg:以何种方式运行进程
  • ...:运行该进程的选项
  • 最后以NULL结尾

与刚刚的execl不同的是,第一个参数从pathname路径,变成了file文件名。该接口的意思是:不用指明路径,只需指明替换的进程的名称,然后会自动去环境变量PATH指定的路径中查找,或者会自动在当前目录下查找。例如要执行ls -a -l,但是我们用了execlp接口,ls是系统自带的指令,所以不用指明路径,系统会自己去查找。

execle接口

函数原型:

int execle(const char *pathname, const char *arg, ... /*, (char *) NULL, char *const envp[] */);
  • pathname:用于指定替换的进程的路径
  • arg:以何种方式运行进程
  • ...:以何种形式执行进程
  • NULL
  • char* const envp[] :指针数组,存储环境变量。一般来说,进程替换后,进程的环境变量是会用原先的环境变量的。

例如,

execv接口

函数原型如下:

int execv(const char *pathname, char *const argv[]);

相比于execl,其少了一个...的可变参数,改为了一个argv数组,而...就是用来指定以何种方式调用进程,或者说指定选项的,带有v系列的接口,将这些选项存储在一个数组中,然后把数组传入,不过注意该数组最后一个元素也要放NULL空指针。

execvp,execvpe同理不用指明路径,execvpe需要带环境变量。

事实上 , 只有 execve 是真正的系统调用 , 其它五个函数最终都调用 execve, 所以 execve man 手册 第 2 , 其它函数在
man 手册第 3 节。这些函数之间的关系如下图所示。

相关推荐

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-18 09:46:07       66 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-18 09:46:07       70 阅读
  3. 在Django里面运行非项目文件

    2024-07-18 09:46:07       57 阅读
  4. Python语言-面向对象

    2024-07-18 09:46:07       68 阅读

热门阅读

  1. 关于redis单线程却能支持高并发业务的原因

    2024-07-18 09:46:07       20 阅读
  2. 软件测试之单元测试

    2024-07-18 09:46:07       23 阅读
  3. C语言经典例题-4

    2024-07-18 09:46:07       16 阅读
  4. Python输出格式_Day4

    2024-07-18 09:46:07       21 阅读
  5. react页面指定dom转pdf导出

    2024-07-18 09:46:07       19 阅读
  6. 树莓派docker安装lnmp

    2024-07-18 09:46:07       18 阅读
  7. 人像视频预处理v1.2 优化检测、处理速度

    2024-07-18 09:46:07       21 阅读
  8. c++ extern 关键字

    2024-07-18 09:46:07       22 阅读
  9. 【C++】C++ 文件模式标志

    2024-07-18 09:46:07       23 阅读
  10. nginx域名跳转到另一个域名

    2024-07-18 09:46:07       22 阅读