【Linux的进程篇章 - 进程程序替换】

本文详细探讨了Linux中的进程程序替换,通过execl系列函数和execve系统调用来理解其工作原理,包括如何执行新程序、替换过程的原理、函数参数含义及自定义程序替换等内容。
摘要由CSDN通过智能技术生成

Linux之进程程序替换理解

前言:
前篇开始进行了解学习Linux的fork函数、进城终止以及进城等待等相关知识内容,接下来学习Linux的进程替换,关于exec*函数族的知识,深入地了解这个强大的开源操作系统。
/知识点汇总/

1、进程程序替换

头文件:
#include <unistd.h>
exec*函数族:(…表示可变参数)
1.int execl(const char* path,const char* arg, …);
2.int execlp(const char* file,const char* arg, …);
3.int execle(const char* path,const char* arg, … ,char* const envp[]);
4.int execv(const char* path,char* const argv[]);
5.int execvp(const char* file,char* const argv[]);
6.int execvpe(const char* file,char* const argv[],char* const envp[]);

1.1、先看代码和现象

#include <unistd.h>  
#include <stdio.h>  
  
int main() {  
    printf("这是原程序的代码\n");  
    execl("/bin/ls", "ls", "-l", (char *)NULL);  
    printf("这行代码不会被执行\n");  
    return 0;  
}

在这里插入图片描述
在这里插入图片描述
根据程序现象可知:
利用exec(新的.exe可执行程序)来替换,当前的进程代码和数据.但是仍然是该进程,只是改变的代码和数据,并不创建新的进程
即:老进程的壳子,执行新程序的内容。 — 进程替换技术

在Linux环境中,execl系列函数(包括execl、execlp、execle、execv、execvp和execvpe)是用来执行新的程序的。这些函数替换当前进程的映像为新的程序文件,并从该程序的main函数开始执行。一旦execl或其他exec函数被调用成功,原程序的剩余代码将不会被执行,因为原程序的内存映像已经被新的程序替换了。
换句话说,execl函数会导致当前进程停止执行,并被新的程序取代。新程序从它的main函数开始执行,并且与原程序没有直接的关联。因此,原程序中execl调用之后的任何代码都不会被执行。

1.2、替换的原理

进程 = 内核数据结构 + 代码和数据(此时在这步执行代码的进程替换,用新的程序覆盖掉,并不创建新的进程)
站在被替换的进程角度:本质就是这个程序被加载到内存了。

怎么加载?

exec函数可理解于Linux上的加载函数。 – 即程序替换
此类exec
函数不关心返回值,因为exec*函数只要替换成功,就不会向后继续执行了;只要继续运行原代码了,一定是替换失败了。

1.3、回顾fork函数的应用

利用fork创建子进程,让子进程自己去替换
测试代码:
在这里插入图片描述
创建子进程,让子进程完成任务:

1.之前知识能,让子进程执行父进程代码的一部分
2.现在的exec技术,让子进程执行一个全新的程序。

2、使用所有的替换方法,并且认识函数参数的含义

2.1、exec*函数族

exec函数族:(…表示可变参数)
1.int execl(const char
path,const char* arg, …);
2.int execlp(const char* file,const char* arg, …);
3.int execle(const char* path,const char* arg, … ,char* const envp[]);
4.int execv(const char* path,char* const argv[]);
5.int execvp(const char* file,char* const argv[]);
6.int execvpe(const char* file,char* const argv[],char* const envp[]);

以int execl(const char path,const char arg, …);为例**

l: list列表
path: 表示参数需要带路径,意思通过路径找到被替换的程序。
argv[]: 可理解为命令行参数的形式。命令列表。
…: 可变参数
p:用户可以不传文件的path,只需要传文件名(file)即可。
e:环境变量
注意
a、如果是自定义的环境变量就是整体替换。
b、本质就是,查找这个程序,系统会自动在环境变量PATH中进行查找。
c、所以只要是可执行程序,即进程,那么都可以被替换。

抽象的理解参数就是:你要执行谁(path),你想要怎么执行(命令行参数argv[])

测试代码

int execv(const char* path,char* const argv[]);
int execlp(const char* file,const char* arg, …);
int execvp(const char* file,char* const argv[]);

在这里插入图片描述

2.2、exec替换自定义的程序

我们都是替换的系统命令,能否替换自定义的程序呢?
可以,任何语言(c++/java/python/shell…)编写的可执行程序都可以。
测试代码
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

测试代码

int execle(const char* path,const char* arg, … ,char* const envp[]);
int execvpe(const char* file,char* const argv[],char* const envp[]);
在这里插入图片描述

小结

所以我们就能实现环境变量的三种使用方法:
1.子进程中自定义环境变量;
2.继承老的环境变量给子进程,通过全局的environ
3.老的环境变量进行修改,如putenv()函数,新增环境变量
int putenv(char* string);

测试代码

int putenv(char* string);
在这里插入图片描述

在这里插入图片描述

3、进程的替换的execve系统调用函数

exec*函数族属于3号手册,不属于2号手册的系统调用.

man 3 exec
在这里插入图片描述

只有一个属于系统调用:execve

int execve(const char* filename,char* const argv[],char* const
envp[]);

扩展的exec*函数族底层都是使用的它,扩展出来主要是为了支持不同的使用或应用场景的需求。

  • 20
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值